1 /** 2 * @fileOverview 3 * @author <a href="https://www.labkey.org">LabKey</a> (<a href="mailto:info@labkey.com">info@labkey.com</a>) 4 * @license Copyright (c) 2008-2016 LabKey Corporation 5 * <p/> 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * <p/> 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * <p/> 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * <p/> 18 */ 19 20 /** 21 * @namespace Query static class to programmatically retrieve, insert, update and 22 * delete data from LabKey public queries. <p/> 23 * {@link LABKEY.Query.selectRows} works for all LabKey public queries. However, 24 * {@link LABKEY.Query.updateRows}, {@link LABKEY.Query.insertRows} and 25 * {@link LABKEY.Query.deleteRows} are not available for all tables and queries. 26 * <p>Additional Documentation: 27 * <ul> 28 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=labkeySql"> 29 * LabKey SQL Reference</a></li> 30 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 31 * How To Find schemaName, queryName & viewName</a></li> 32 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=javascriptTutorial">LabKey JavaScript API Tutorial</a> and 33 * <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=reagentRequest">Demo</a></li> 34 * </ul> 35 * </p> 36 */ 37 LABKEY.Query = new function() 38 { 39 function sendJsonQueryRequest(config) 40 { 41 var dataObject = { 42 schemaName : config.schemaName, 43 queryName : config.queryName, 44 rows : config.rows || config.rowDataArray, 45 transacted : config.transacted, 46 extraContext : config.extraContext 47 }; 48 49 var requestConfig = { 50 url : LABKEY.ActionURL.buildURL("query", config.action, config.containerPath), 51 method : 'POST', 52 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 53 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 54 jsonData : dataObject, 55 headers : { 56 'Content-Type' : 'application/json' 57 } 58 }; 59 60 if (LABKEY.Utils.isDefined(config.timeout)) 61 requestConfig.timeout = config.timeout; 62 63 return LABKEY.Ajax.request(requestConfig); 64 } 65 66 function getContentType(response) 67 { 68 //The response object is not actually the XMLHttpRequest object 69 //it's a 'synthesized' object provided by Ext to help on IE 6 70 //http://extjs.com/forum/showthread.php?t=27190&highlight=getResponseHeader 71 return response && response.getResponseHeader ? response.getResponseHeader('Content-Type') : null; 72 } 73 74 function getSuccessCallbackWrapper(callbackFn, stripHiddenCols, scope, requiredVersion) 75 { 76 if (requiredVersion && (requiredVersion === 13.2 || requiredVersion === "13.2" || requiredVersion === 16.2)) { 77 return LABKEY.Utils.getCallbackWrapper(function(data, response, options){ 78 if (data && callbackFn) 79 callbackFn.call(scope || this, new LABKEY.Query.Response(data), response, options); 80 }, this); 81 } 82 83 return LABKEY.Utils.getCallbackWrapper(function(data, response, options){ 84 if (data && data.rows && stripHiddenCols) 85 stripHiddenColData(data); 86 if (callbackFn) 87 callbackFn.call(scope || this, data, options, response); 88 }, this); 89 } 90 91 function stripHiddenColData(data) 92 { 93 //gather the set of hidden columns 94 var hiddenCols = []; 95 var newColModel = []; 96 var newMetaFields = []; 97 var colModel = data.columnModel; 98 for(var idx = 0; idx < colModel.length; ++idx) 99 { 100 if (colModel[idx].hidden) 101 hiddenCols.push(colModel[idx].dataIndex); 102 else 103 { 104 newColModel.push(colModel[idx]); 105 newMetaFields.push(data.metaData.fields[idx]); 106 } 107 } 108 109 //reset the columnModel and metaData.fields to include only the non-hidden items 110 data.columnModel = newColModel; 111 data.metaData.fields = newMetaFields; 112 113 //delete column values for any columns in the hiddenCols array 114 var row; 115 for(idx = 0; idx < data.rows.length; ++idx) 116 { 117 row = data.rows[idx]; 118 for(var idxHidden = 0; idxHidden < hiddenCols.length; ++idxHidden) 119 { 120 delete row[hiddenCols[idxHidden]]; 121 delete row[LABKEY.Query.URL_COLUMN_PREFIX + hiddenCols[idxHidden]]; 122 } 123 } 124 } 125 126 function configFromArgs(args) 127 { 128 return { 129 schemaName: args[0], 130 queryName: args[1], 131 rows: args[2], 132 successCallback: args[3], 133 errorCallback: args[4] 134 }; 135 } 136 137 function getMethod(value) 138 { 139 if (value && (value.toUpperCase() === 'GET' || value.toUpperCase() === 'POST')) 140 return value.toUpperCase(); 141 return 'GET'; 142 } 143 144 // public methods: 145 /** @scope LABKEY.Query */ 146 return { 147 148 /** 149 * An enumeration of the various container filters available. Note that not all 150 * data types and queries can contain that spans multiple containers. In those cases, 151 * all values will behave the same as current and show only data in the current container. 152 * The options are as follows: 153 * <ul> 154 * <li><b>current:</b> Include the current folder only</li> 155 * <li><b>currentAndFirstChildren:</b> Include the current folder and all first children, excluding workbooks</li> 156 * <li><b>currentAndSubfolders:</b> Include the current folder and all subfolders</li> 157 * <li><b>currentPlusProject:</b> Include the current folder and the project that contains it</li> 158 * <li><b>currentAndParents:</b> Include the current folder and its parent folders</li> 159 * <li><b>currentPlusProjectAndShared:</b> Include the current folder plus its project plus any shared folders</li> 160 * <li><b>allFolders:</b> Include all folders for which the user has read permission</li> 161 * </ul> 162 */ 163 containerFilter : { 164 current: "Current", 165 currentAndFirstChildren: "CurrentAndFirstChildren", 166 currentAndSubfolders: "CurrentAndSubfolders", 167 currentPlusProject: "CurrentPlusProject", 168 currentAndParents: "CurrentAndParents", 169 currentPlusProjectAndShared: "CurrentPlusProjectAndShared", 170 allFolders: "AllFolders" 171 }, 172 173 174 /** 175 * Execute arbitrary LabKey SQL. For more information, see the 176 * <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=labkeySql"> 177 * LabKey SQL Reference</a>. 178 * @param config An object which contains the following configuration properties. 179 * @param {String} config.schemaName name of the schema to query. 180 * @param {String} config.sql The LabKey SQL to execute. 181 * @param {String} [config.containerPath] The path to the container in which the schema and query are defined, 182 * if different than the current container. If not supplied, the current container's path will be used. 183 * @param {String} [config.containerFilter] One of the values of {@link LABKEY.Query.containerFilter} that sets 184 * the scope of this query. Defaults to containerFilter.current, and is interpreted relative to 185 * config.containerPath. 186 * @param {Function} config.success 187 Function called when the "selectRows" function executes successfully. 188 This function will be called with the following arguments: 189 <ul> 190 <li> 191 <b>data:</b> If config.requiredVersion is not set, or set to "8.3", the success handler will be 192 passed a {@link LABKEY.Query.SelectRowsResults} object. If set to "9.1" the success handler will 193 be passed a {@link LABKEY.Query.ExtendedSelectRowsResults} object. If set to "13.2" the succes 194 handler will be passed a {@link LABKEY.Query.Response} object. 195 </li> 196 <li><b>responseObj:</b> The XMLHttpResponseObject instance used to make the AJAX request</li> 197 <li><b>options:</b> The options used for the AJAX request</li> 198 </ul> 199 * @param {Function} [config.failure] Function called when execution of the "executeSql" function fails. 200 * See {@link LABKEY.Query.selectRows} for more information on the parameters passed to this function. 201 * @param {Integer} [config.maxRows] The maximum number of rows to return from the server (defaults to returning all rows). 202 * @param {Integer} [config.offset] The index of the first row to return from the server (defaults to 0). 203 * Use this along with the maxRows config property to request pages of data. 204 * @param {Boolean} [config.includeTotalCount] Include the total number of rows available (defaults to true). 205 * If false totalCount will equal number of rows returned (equal to maxRows unless maxRows == 0). 206 * @param {String} [config.sort] A sort specification to apply over the rows returned by the SQL. In general, 207 * you should either include an ORDER BY clause in your SQL, or specific a sort specification in this config property, 208 * but not both. The value of this property should be a comma-delimited list of column names you want to sort by. Use 209 * a - prefix to sort a column in descending order (e.g., 'LastName,-Age' to sort first by LastName, then by Age descending). 210 * @param {Boolean} [config.saveInSession] Whether or not the definition of this query should be stored for reuse during the current session. 211 * If true, all information required to recreate the query will be stored on the server and a unique query name will be passed to the 212 * success callback. This temporary query name can be used by all other API methods, including Query Web Part creation, for as long 213 * as the current user's session remains active. 214 * @param {Boolean} [config.includeDetailsColumn] Include the Details link column in the set of columns (defaults to false). 215 * If included, the column will have the name "~~Details~~". The underlying table/query must support details links 216 * or the column will be omitted in the response. 217 * @param {Object} [config.parameters] Map of name (string)/value pairs for the values of parameters if the SQL 218 * references underlying queries that are parameterized. For example, the following passes two parameters to the query: {'Gender': 'M', 'CD4': '400'}. 219 * The parameters are written to the request URL as follows: query.param.Gender=M&query.param.CD4=400. For details on parameterized SQL queries, see 220 * <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=paramsql">Parameterized SQL Queries</a>. 221 * @param {Double} [config.requiredVersion] If not set, or set to "8.3", the success handler will be passed a {@link LABKEY.Query.SelectRowsResults} 222 object. If set to "9.1" the success handler will be passed a {@link LABKEY.Query.ExtendedSelectRowsResults} 223 object. If set to "13.2" the success handler will be passed a {@link LABKEY.Query.Response} object. 224 The main difference between SelectRowsResults and ExtendedSelectRowsResults is that each column in each row 225 will be another object (not just a scalar value) with a "value" property as well as other related properties 226 (url, mvValue, mvIndicator, etc.). In the LABKEY.Query.Response format each row will be an instance of 227 {@link LABKEY.Query.Row}. 228 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 229 * generating a timeout error (defaults to 30000). 230 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 231 * @returns {Mixed} In client-side scripts, this method will return a transaction id 232 * for the async request that can be used to cancel the request 233 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 234 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 235 * @example Example, from the Reagent Request Confirmation <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=reagentRequestConfirmation">Tutorial</a> and <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=Confirmation">Demo</a>: <pre name="code" class="xml"> 236 // This snippet extracts a table of UserID, TotalRequests and 237 // TotalQuantity from the "Reagent Requests" list. 238 // Upon success, the writeTotals function (not included here) uses the 239 // returned data object to display total requests and total quantities. 240 241 LABKEY.Query.executeSql({ 242 containerPath: 'home/Study/demo/guestaccess', 243 schemaName: 'lists', 244 sql: 'SELECT "Reagent Requests".UserID AS UserID, \ 245 Count("Reagent Requests".UserID) AS TotalRequests, \ 246 Sum("Reagent Requests".Quantity) AS TotalQuantity \ 247 FROM "Reagent Requests" Group BY "Reagent Requests".UserID', 248 success: writeTotals 249 }); </pre> 250 251 * @see LABKEY.Query.SelectRowsOptions 252 * @see LABKEY.Query.SelectRowsResults 253 * @see LABKEY.Query.ExtendedSelectRowsResults 254 * @see LABKEY.Query.Response 255 */ 256 executeSql : function(config) 257 { 258 var dataObject = { 259 schemaName: config.schemaName, 260 sql: config.sql 261 }; 262 263 // Work with Ext4.Ajax.request 264 if (config.saveInSession !== undefined && config.saveInSession !== null) 265 dataObject.saveInSession = config.saveInSession; 266 267 //set optional parameters 268 if (config.maxRows !== undefined && config.maxRows >= 0) 269 dataObject.maxRows = config.maxRows; 270 if (config.offset && config.offset > 0) 271 dataObject.offset = config.offset; 272 if (config.includeTotalCount != undefined) 273 dataObject.includeTotalCount = config.includeTotalCount; 274 275 if (config.containerFilter) 276 dataObject.containerFilter = config.containerFilter; 277 278 if (config.requiredVersion) 279 dataObject.apiVersion = config.requiredVersion; 280 281 if (config.includeStyle) 282 dataObject.includeStyle = config.includeStyle; 283 284 var qsParams = {}; 285 if (config.sort) 286 qsParams["query.sort"] = config.sort; 287 288 if (config.parameters) 289 { 290 for (var n in config.parameters) 291 { 292 if (config.parameters.hasOwnProperty(n)) 293 { 294 qsParams["query.param." + n] = config.parameters[n]; 295 } 296 } 297 } 298 299 var requestConfig = { 300 url : LABKEY.ActionURL.buildURL("query", "executeSql.api", config.containerPath, qsParams), 301 method : 'POST', 302 success: getSuccessCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.stripHiddenColumns, config.scope, config.requiredVersion), 303 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 304 jsonData : dataObject, 305 headers : { 306 'Content-Type' : 'application/json' 307 } 308 }; 309 310 if (LABKEY.Utils.isDefined(config.timeout)) 311 requestConfig.timeout = config.timeout; 312 313 return LABKEY.Ajax.request(requestConfig); 314 }, 315 316 /** 317 * Bulk import data rows into a table. 318 * One of 'text', 'path', 'moduleResource', or 'file' is required and cannot be combined. 319 * 320 * @param {Object} config An object which contains the following configuration properties. 321 * @param {String} config.schemaName Name of a schema defined within the current container. 322 * @param {String} config.queryName Name of a query table associated with the chosen schema. 323 * @param {File} [config.file] A <a href='https://developer.mozilla.org/en-US/docs/DOM/File'><code>File</code></a> object or a file input element to upload to the server. 324 * @param {String} [config.text] Text to import. 325 * @param {String} [config.path] Path to resource under webdav tree. E.g. "/_webdav/MyProject/@files/data.tsv" 326 * @param {String} [config.module] Module name to use when resolving a module resource. 327 * @param {String} [config.moduleResource] A file resource within the module to import. 328 * @param {String} [config.importIdentity] When true, auto-increment key columns may be imported from the data. 329 * @param {String} [config.importLookupByAlternateKey] When true, lookup columns can be imported by their alternate keys instead of the primary key. 330 * For example, if a column is a lookup to a SampleSet, the imported value can be the Sample's name since names must be unique within a SampleSet. 331 * @param {Function} [config.success] Function called when the "importData" function executes successfully. 332 Will be called with the following arguments: 333 An object containing success and rowCount properties. 334 * @param {Function} [config.failure] Function called importing data fails. 335 * @param {String} [config.containerPath] The container path in which the schema and query name are defined. 336 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 337 * generating a timeout error (defaults to 30000). 338 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 339 * @returns {Mixed} In client-side scripts, this method will return a transaction id 340 * for the async request that can be used to cancel the request 341 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 342 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 343 * @example Example, importing tsv data from a module: <pre name="code" class="javascript"> 344 LABKEY.Query.importData({ 345 schemaName: 'lists', 346 queryName: 'People', 347 // reference to <input type='file' id='file'> 348 file: document.getElementById('file') 349 }, 350 });</pre> 351 * @example Example, importing tsv data from a module: <pre name="code" class="javascript"> 352 LABKEY.Query.importData({ 353 schemaName: 'lists', 354 queryName: 'People', 355 module: 'mymodule', 356 moduleResource: '/data/lists/People.tsv' 357 }, 358 });</pre> 359 */ 360 importData : function (config) 361 { 362 if (!window.FormData) 363 throw new Error("modern browser required"); 364 365 var form = new FormData(); 366 367 form.append("schemaName", config.schemaName); 368 form.append("queryName", config.queryName); 369 if (config.text) 370 form.append("text", config.text); 371 if (config.path) 372 form.append("path", config.path); 373 if (config.format) 374 form.append("format", config.format); 375 if (config.module) 376 form.append("module", config.module); 377 if (config.moduleResource) 378 form.append("moduleResource", config.moduleResource); 379 if (config.importIdentity) 380 form.append("importIdentity", config.importIdentity); 381 if (config.importLookupByAlternateKey) 382 form.append("importLookupByAlternateKey", config.importLookupByAlternateKey); 383 384 if (config.file) { 385 if (config.file instanceof File) 386 form.append("file", config.file); 387 else if (config.file.tagName == "INPUT" && config.file.files.length > 0) 388 form.append("file", config.file.files[0]); 389 } 390 391 return LABKEY.Ajax.request({ 392 url: LABKEY.ActionURL.buildURL("query", "import.api", config.containerPath), 393 method: 'POST', 394 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope, false), 395 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 396 form: form, 397 timeout: config.timeout 398 }); 399 }, 400 401 /** 402 * Select rows. 403 * @param {Object} config An object which contains the following configuration properties. 404 * @param {String} config.schemaName Name of a schema defined within the current container. See also: <a class="link" 405 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 406 How To Find schemaName, queryName & viewName</a>. 407 * @param {String} config.queryName Name of a query table associated with the chosen schema. See also: <a class="link" 408 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 409 How To Find schemaName, queryName & viewName</a>. 410 * @param {Function} config.success 411 Function called when the "selectRows" function executes successfully. 412 This function will be called with the following arguments: 413 <ul> 414 <li> 415 <b>data:</b> If config.requiredVersion is not set, or set to "8.3", the success handler will be 416 passed a {@link LABKEY.Query.SelectRowsResults} object. If set to "9.1" the success handler will 417 be passed a {@link LABKEY.Query.ExtendedSelectRowsResults} object. If set to "13.2" the succes 418 handler will be passed a {@link LABKEY.Query.Response} object. 419 </li> 420 <li><b>responseObj:</b> The XMLHttpResponseObject instance used to make the AJAX request</li> 421 <li><b>options:</b> The options used for the AJAX request</li> 422 </ul> 423 * @param {Function} [config.failure] Function called when execution of the "selectRows" function fails. 424 * This function will be called with the following arguments: 425 <ul> 426 <li><b>errorInfo:</b> an object describing the error with the following fields: 427 <ul> 428 <li><b>exception:</b> the exception message</li> 429 <li><b>exceptionClass:</b> the Java class of the exception thrown on the server</li> 430 <li><b>stackTrace:</b> the Java stack trace at the point when the exception occurred</li> 431 </ul> 432 </li> 433 <li><b>responseObj:</b> the XMLHttpResponseObject instance used to make the AJAX request</li> 434 <li><b>options:</b> the options used for the AJAX request</li> 435 </ul> 436 * @param {Array} [config.filterArray] Array of objects created by {@link LABKEY.Filter.create}. 437 * @param {Object} [config.parameters] Map of name (string)/value pairs for the values of parameters if the SQL 438 * references underlying queries that are parameterized. For example, the following passes two parameters to the query: {'Gender': 'M', 'CD4': '400'}. 439 * The parameters are written to the request URL as follows: query.param.Gender=M&query.param.CD4=400. For details on parameterized SQL queries, see 440 * <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=paramsql">Parameterized SQL Queries</a>. 441 * @param {String} [config.sort] String description of the sort. It includes the column names 442 * listed in the URL of a sorted data region (with an optional minus prefix to indicate 443 * descending order). In the case of a multi-column sort, up to three column names can be 444 * included, separated by commas. 445 * @param {String} [config.viewName] The name of a custom view saved on the server for the specified query. 446 * @param {String} [config.columns] An Array of columns or a comma-delimited list of column names you wish to select from the specified 447 * query. By default, selectRows will return the set of columns defined in the default value for this query, 448 * as defined via the Customize View user interface on the server. You can override this by specifying a list 449 * of column names in this parameter, separated by commas. The names can also include references to related 450 * tables (e.g., 'RelatedPeptide/Peptide' where 'RelatedPeptide is the name of a foreign key column in the 451 * base query, and 'Peptide' is the name of a column in the related table). 452 * @param {String} [config.containerPath] The path to the container in which the schema and query are defined, 453 * if different than the current container. If not supplied, the current container's path will be used. 454 * @param {String} [config.containerFilter] One of the values of {@link LABKEY.Query.containerFilter} that sets 455 * the scope of this query. Defaults to containerFilter.current, and is interpreted relative to 456 * config.containerPath. 457 * @param {String} [config.showRows] Either 'paginated' (the default) 'selected', 'unselected', 'all', or 'none'. 458 * When 'paginated', the maxRows and offset parameters can be used to page through the query's result set rows. 459 * When 'selected' or 'unselected' the set of rows selected or unselected by the user in the grid view will be returned. 460 * You can programatically get and set the selection using the {@link LABKEY.DataRegion.setSelected} APIs. 461 * Setting <code>config.maxRows</code> to -1 is the same as 'all' 462 * and setting <code>config.maxRows</code> to 0 is the same as 'none'. 463 * @param {Integer} [config.maxRows] The maximum number of rows to return from the server (defaults to 100000). 464 * If you want to return all possible rows, set this config property to -1. 465 * @param {Integer} [config.offset] The index of the first row to return from the server (defaults to 0). 466 * Use this along with the maxRows config property to request pages of data. 467 * @param {Boolean} [config.includeTotalCount] Include the total number of rows available (defaults to true). 468 * If false totalCount will equal number of rows returned (equal to maxRows unless maxRows == 0). 469 * @param {Boolean} [config.includeDetailsColumn] Include the Details link column in the set of columns (defaults to false). 470 * If included, the column will have the name "~~Details~~". The underlying table/query must support details links 471 * or the column will be omitted in the response. 472 * @param {Boolean} [config.includeUpdateColumn] Include the Update (or edit) link column in the set of columns (defaults to false). 473 * If included, the column will have the name "~~Update~~". The underlying table/query must support update links 474 * or the column will be omitted in the response. 475 * @param {String} [config.selectionKey] Unique string used by selection APIs as a key when storing or retrieving the selected items for a grid. 476 * Not used unless <code>config.showRows</code> is 'selected' or 'unselected'. 477 * @param {Boolean} [config.ignoreFilter] If true, the command will ignore any filter that may be part of the chosen view. 478 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 479 * generating a timeout error (defaults to 30000). 480 * @param {Double} [config.requiredVersion] If not set, or set to "8.3", the success handler will be passed a {@link LABKEY.Query.SelectRowsResults} 481 object. If set to "9.1" the success handler will be passed a {@link LABKEY.Query.ExtendedSelectRowsResults} 482 object. If set to "13.2" the success handler will be passed a {@link LABKEY.Query.Response} object. 483 The main difference between SelectRowsResults and ExtendedSelectRowsResults is that each column in each row 484 will be another object (not just a scalar value) with a "value" property as well as other related properties 485 (url, mvValue, mvIndicator, etc.). In the LABKEY.Query.Response format each row will an instance of 486 {@link LABKEY.Query.Row}. 487 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 488 * @returns {Mixed} In client-side scripts, this method will return a transaction id 489 * for the async request that can be used to cancel the request 490 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 491 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 492 * @example Example: <pre name="code" class="xml"> 493 <script type="text/javascript"> 494 function onFailure(errorInfo, options, responseObj) 495 { 496 if (errorInfo && errorInfo.exception) 497 alert("Failure: " + errorInfo.exception); 498 else 499 alert("Failure: " + responseObj.statusText); 500 } 501 502 function onSuccess(data) 503 { 504 alert("Success! " + data.rowCount + " rows returned."); 505 } 506 507 LABKEY.Query.selectRows({ 508 schemaName: 'lists', 509 queryName: 'People', 510 columns: ['Name', 'Age'], 511 success: onSuccess, 512 failure: onFailure 513 }); 514 </script> </pre> 515 * @see LABKEY.Query.SelectRowsOptions 516 * @see LABKEY.Query.SelectRowsResults 517 * @see LABKEY.Query.ExtendedSelectRowsResults 518 * @see LABKEY.Query.Response 519 */ 520 selectRows : function(config) 521 { 522 //check for old-style separate arguments 523 if (arguments.length > 1) 524 { 525 config = { 526 schemaName: arguments[0], 527 queryName: arguments[1], 528 success: arguments[2], 529 errorCallback: arguments[3], 530 filterArray: arguments[4], 531 sort: arguments[5], 532 viewName: arguments[6] 533 }; 534 } 535 536 if (!config.schemaName) 537 throw "You must specify a schemaName!"; 538 if (!config.queryName) 539 throw "You must specify a queryName!"; 540 541 config.dataRegionName = config.dataRegionName || "query"; 542 543 var dataObject = LABKEY.Query.buildQueryParams( 544 config.schemaName, 545 config.queryName, 546 config.filterArray, 547 config.sort, 548 config.dataRegionName 549 ); 550 551 if (!config.showRows || config.showRows == 'paginated') 552 { 553 if (config.offset) 554 dataObject[config.dataRegionName + '.offset'] = config.offset; 555 556 if (config.maxRows != undefined) 557 { 558 if (config.maxRows < 0) 559 dataObject[config.dataRegionName + '.showRows'] = "all"; 560 else 561 dataObject[config.dataRegionName + '.maxRows'] = config.maxRows; 562 } 563 } 564 else if (config.showRows in {'all':true, 'selected':true, 'unselected':true, 'none':true}) 565 { 566 dataObject[config.dataRegionName + '.showRows'] = config.showRows; 567 } 568 569 570 if (config.viewName) 571 dataObject[config.dataRegionName + '.viewName'] = config.viewName; 572 573 if (config.columns) 574 dataObject[config.dataRegionName + '.columns'] = LABKEY.Utils.isArray(config.columns) ? config.columns.join(",") : config.columns; 575 576 if (config.selectionKey) 577 dataObject[config.dataRegionName + '.selectionKey'] = config.selectionKey; 578 579 if (config.ignoreFilter) 580 dataObject[config.dataRegionName + '.ignoreFilter'] = 1; 581 582 if (config.parameters) 583 { 584 for (var propName in config.parameters) 585 { 586 if (config.parameters.hasOwnProperty(propName)) 587 dataObject[config.dataRegionName + '.param.' + propName] = config.parameters[propName]; 588 } 589 } 590 591 if (config.requiredVersion) 592 dataObject.apiVersion = config.requiredVersion; 593 594 if (config.containerFilter) 595 dataObject.containerFilter = config.containerFilter; 596 597 if (config.includeTotalCount) 598 dataObject.includeTotalCount = config.includeTotalCount; 599 600 if (config.includeDetailsColumn) 601 dataObject.includeDetailsColumn = config.includeDetailsColumn; 602 603 if (config.includeUpdateColumn) 604 dataObject.includeUpdateColumn = config.includeUpdateColumn; 605 606 if (config.includeStyle) 607 dataObject.includeStyle = config.includeStyle; 608 609 var requestConfig = { 610 url : LABKEY.ActionURL.buildURL('query', 'getQuery.api', config.containerPath), 611 method : getMethod(config.method), 612 success: getSuccessCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.stripHiddenColumns, config.scope, config.requiredVersion), 613 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 614 params : dataObject 615 }; 616 617 if (LABKEY.Utils.isDefined(config.timeout)) 618 requestConfig.timeout = config.timeout; 619 620 return LABKEY.Ajax.request(requestConfig); 621 }, 622 623 /** 624 * Select Distinct Rows 625 * @param {Object} config An object which contains the following configuration properties. 626 * @param {String} config.schemaName Name of a schema defined within the current container. See also: <a class="link" 627 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 628 How To Find schemaName, queryName & viewName</a>. 629 * @param {String} config.queryName Name of a query table associated with the chosen schema. See also: <a class="link" 630 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 631 How To Find schemaName, queryName & viewName</a>. 632 * @param {String} config.column A single column for which the distinct results will be requested. This column 633 * must exist within the specified query. 634 * @param {String} [config.containerFilter] One of the values of {@link LABKEY.Query.containerFilter} that sets 635 * the scope of this query. Defaults to containerFilter.current, and is interpreted relative to 636 * config.containerPath. 637 * @param {Object} [config.parameters] Map of name (string)/value pairs for the values of parameters if the SQL 638 * references underlying queries that are parameterized. For example, the following passes two parameters to the query: {'Gender': 'M', 'CD4': '400'}. 639 * The parameters are written to the request URL as follows: query.param.Gender=M&query.param.CD4=400. For details on parameterized SQL queries, see 640 * <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=paramsql">Parameterized SQL Queries</a>. 641 * @param {Array} [config.filterArray] Array of objects created by {@link LABKEY.Filter.create}. 642 * @param {String} [config.viewName] Name of a view to use. This is potentially important if this view contains filters on the data. 643 * @param {Function} config.success 644 * @param {Function} config.failure 645 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 646 */ 647 selectDistinctRows : function(config) 648 { 649 if (!config.schemaName) 650 throw "You must specify a schemaName!"; 651 if (!config.queryName) 652 throw "You must specify a queryName!"; 653 if (!config.column) 654 throw "You must specify a column!"; 655 656 config.dataRegionName = config.dataRegionName || "query"; 657 658 var dataObject = LABKEY.Query.buildQueryParams( 659 config.schemaName, 660 config.queryName, 661 config.filterArray, 662 config.sort, 663 config.dataRegionName 664 ); 665 666 dataObject[config.dataRegionName + '.columns'] = config.column; 667 668 if (config.viewName) 669 dataObject[config.dataRegionName + '.viewName'] = config.viewName; 670 671 if (config.maxRows && config.maxRows >= 0) 672 dataObject.maxRows = config.maxRows; 673 674 if (config.containerFilter) 675 dataObject.containerFilter = config.containerFilter; 676 677 if (config.parameters) 678 { 679 for (var propName in config.parameters) 680 { 681 if (config.parameters.hasOwnProperty(propName)) 682 dataObject[config.dataRegionName + '.param.' + propName] = config.parameters[propName]; 683 } 684 } 685 686 if (config.ignoreFilter) 687 { 688 dataObject[config.dataRegionName + '.ignoreFilter'] = true; 689 } 690 691 return LABKEY.Ajax.request({ 692 url : LABKEY.ActionURL.buildURL('query', 'selectDistinct.api', config.containerPath), 693 method : getMethod(config.method), 694 success: getSuccessCallbackWrapper(LABKEY.Utils.getOnSuccess(config), false, config.scope), 695 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 696 params : dataObject 697 }); 698 }, 699 700 701 /** 702 * Returns a list of reports, views and/or datasets in a container 703 * @param config 704 * @param {String} [config.containerPath] A container path in which to execute this command. If not provided, the current container will be used 705 * @param {Array} [config.dataTypes] An array of data types to return, which can be any of: 'reports', 'datasets' or 'queries'. If null, all will be returned 706 * @param {Function} [config.success] A function called on success. It will be passed a single argument with the following properties: 707 * <ul> 708 * <li>data: An array with one element per dataview. Each view is a map with the following properties: 709 * <ul> 710 * <li>access: 711 * <li>allowCustomThumbnail: A flag indicating whether the thumbnail can be customized 712 * <li>category: The category to which this item has been assigned 713 * <li>categoryDisplayOrder: The display order within that category 714 * <li>container: The container where this dataView is defined 715 * <li>created: The displayName of the user who created the item 716 * <li>createdByUserId: The user Id of the user who created the item 717 * <li>dataType: The dataType of this item, either queries, reports or datasets 718 * <li>detailsUrl: The url that will display additional details about this item 719 * <li>icon: The url of the icon for this report 720 * <li>id: The unique Id of this item 721 * <li>reportId: The unique report Id if this item is a report. Value is null if this item is not a report. 722 * <li>modified: The date this item was last modified 723 * <li>name: The display name of this item 724 * <li>runUrl: The url that can be used to execute this report 725 * <li>shared: A flag indicating whether this item is shared 726 * <li>thumbnail: The url of this item's thumbnail image 727 * <li>type: The display string for the Data Type. 728 * <li>visible: A flag indicating whether this report is visible or hidden 729 * </ul> 730 * <li>types: a map of each dataType, and a boolean indicating whether it was included in the results (this is based on the dataTypes param in the config) 731 * </ul> 732 * @param {Function} [config.failure] A function called when execution of "getDataViews" fails. 733 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 734 */ 735 getDataViews : function(config) 736 { 737 var dataObject = { 738 includeData: true, 739 includeMetadata: false 740 }; 741 if(config.dataTypes) 742 dataObject.dataTypes = config.dataTypes; 743 744 var callbackFn = LABKEY.Utils.getOnSuccess(config); 745 var success = LABKEY.Utils.getCallbackWrapper(function(data, response, options){ 746 if (callbackFn) 747 callbackFn.call(config.scope || this, data.data, options, response); 748 }, this); 749 750 return LABKEY.Ajax.request({ 751 url : LABKEY.ActionURL.buildURL('reports', 'browseData.api', config.containerPath), 752 method : 'POST', 753 success: success, 754 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 755 jsonData : dataObject, 756 headers : { 757 'Content-Type' : 'application/json' 758 } 759 }); 760 }, 761 762 /** 763 * Update rows. 764 * @param {Object} config An object which contains the following configuration properties. 765 * @param {String} config.schemaName Name of a schema defined within the current container. See also: <a class="link" 766 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 767 How To Find schemaName, queryName & viewName</a>. 768 * @param {String} config.queryName Name of a query table associated with the chosen schema. See also: <a class="link" 769 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 770 How To Find schemaName, queryName & viewName</a>. 771 * @param {Array} config.rows Array of record objects in which each object has a property for each field. 772 * The row array must include the primary key column values and values for 773 * other columns you wish to update. 774 * @param {Object} [config.extraContext] <b>Experimental:</b> Optional extra context object passed into the transformation/validation script environment. 775 * @param {Function} config.success Function called when the "updateRows" function executes successfully. 776 Will be called with arguments: 777 the parsed response data ({@link LABKEY.Query.ModifyRowsResults}), the XMLHttpRequest object and 778 (optionally) the "options" object ({@link LABKEY.Query.ModifyRowsOptions}). 779 * @param {Function} [config.failure] Function called when execution of the "updateRows" function fails. 780 * See {@link LABKEY.Query.selectRows} for more information on the parameters passed to this function. 781 * @param {String} [config.containerPath] The container path in which the schema and query name are defined. 782 * If not supplied, the current container path will be used. 783 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 784 * generating a timeout error (defaults to 30000). 785 * @param {boolean} [config.transacted] Whether all of the updates should be done in a single transaction, so they all succeed or all fail. Defaults to true 786 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 787 * @returns {Mixed} In client-side scripts, this method will return a transaction id 788 * for the async request that can be used to cancel the request 789 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 790 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 791 * @see LABKEY.Query.ModifyRowsResults 792 * @see LABKEY.Query.ModifyRowsOptions 793 */ 794 updateRows : function(config) 795 { 796 if (arguments.length > 1) 797 config = configFromArgs(arguments); 798 config.action = "updateRows.api"; 799 return sendJsonQueryRequest(config); 800 }, 801 802 /** 803 * Save inserts, updates, and/or deletes to potentially multiple tables with a single request. 804 * @param {Object} config An object which contains the following configuration properties. 805 * @param {Array} config.commands An array of all of the update/insert/delete operations to be performed. 806 * Each command has the following structure: 807 * @param {String} config.commands[].schemaName Name of a schema defined within the current container. See also: <a class="link" 808 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 809 How To Find schemaName, queryName & viewName</a>. 810 * @param {String} config.commands[].queryName Name of a query table associated with the chosen schema. See also: <a class="link" 811 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 812 How To Find schemaName, queryName & viewName</a>. 813 * @param {String} config.commands[].command Name of the command to be performed. Must be one of "insert", "update", or "delete". 814 * @param {Array} config.commands[].rows An array of data for each row to be changed. See {@link LABKEY.Query.insertRows}, 815 * {@link LABKEY.Query.updateRows}, or {@link LABKEY.Query.deleteRows} for requirements of what data must be included for each row. 816 * @param {Object} [config.commands[].extraContext] <b>Experimental:</b> Optional extra context object passed into the transformation/validation script environment. 817 * @param {Object} [config.extraContext] <b>Experimental:</b> Optional extra context object passed into the transformation/validation script environment. 818 * The extraContext at the command-level will be merged with the extraContext at the top-level of the config. 819 * @param {Function} config.success Function called when the "saveRows" function executes successfully. 820 Called with arguments: 821 <ul> 822 <li>an object with the following properties: 823 <ul> 824 <li><strong>result</strong>: an array of parsed response data ({@link LABKEY.Query.ModifyRowsResults}) (one for each command in the request) 825 <li><strong>errorCount</strong>: an integer, with the total number of errors encountered during the operation 826 <li><strong>committed</strong>: a boolean, indicating if the changes were actually committed to the database 827 </ul> 828 <li>the XMLHttpRequest object</li> 829 <li>(optionally) the "options" object ({@link LABKEY.Query.ModifyRowsOptions})</li> 830 </ul> 831 * @param {Function} [config.failure] Function called if execution of the "saveRows" function fails. 832 * See {@link LABKEY.Query.selectRows} for more information on the parameters passed to this function. 833 * @param {String} [config.containerPath] The container path in which the changes are to be performed. 834 * If not supplied, the current container path will be used. 835 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 836 * generating a timeout error (defaults to 30000). 837 * @param {Double} [config.apiVersion] Version of the API. If this is 13.2 or higher, a request that fails 838 * validation will be returned as a successful response. Use the 'errorCount' and 'committed' properties in the 839 * response to tell if it committed or not. If this is 13.1 or lower (or unspecified), the failure callback 840 * will be invoked instead in the event of a validation failure. 841 * @param {boolean} [config.transacted] Whether all of the row changes for all of the tables 842 * should be done in a single transaction, so they all succeed or all fail. Defaults to true 843 * @param {boolean} [config.validateOnly] Whether or not the server should attempt proceed through all of the 844 * commands, but not actually commit them to the database. Useful for scenarios like giving incremental 845 * validation feedback as a user fills out a UI form, but not actually save anything until they explicitly request 846 * a save. 847 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 848 * @returns {Mixed} In client-side scripts, this method will return a transaction id 849 * for the async request that can be used to cancel the request 850 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 851 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 852 * @see LABKEY.Query.ModifyRowsResults 853 * @see LABKEY.Query.ModifyRowsOptions 854 */ 855 saveRows : function(config) 856 { 857 if (arguments.length > 1) 858 config = configFromArgs(arguments); 859 860 var dataObject = { 861 commands: config.commands, 862 containerPath: config.containerPath, 863 validateOnly : config.validateOnly, 864 transacted : config.transacted, 865 extraContext : config.extraContext, 866 apiVersion : config.apiVersion 867 }; 868 869 var requestConfig = { 870 url : LABKEY.ActionURL.buildURL("query", "saveRows.api", config.containerPath), 871 method : 'POST', 872 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 873 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 874 jsonData : dataObject, 875 headers : { 876 'Content-Type' : 'application/json' 877 } 878 }; 879 880 if (LABKEY.Utils.isDefined(config.timeout)) 881 requestConfig.timeout = config.timeout; 882 883 return LABKEY.Ajax.request(requestConfig); 884 885 }, 886 887 /** 888 * Insert rows. 889 * @param {Object} config An object which contains the following configuration properties. 890 * @param {String} config.schemaName Name of a schema defined within the current container. See also: <a class="link" 891 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 892 How To Find schemaName, queryName & viewName</a>. 893 * @param {String} config.queryName Name of a query table associated with the chosen schema. See also: <a class="link" 894 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 895 How To Find schemaName, queryName & viewName</a>. 896 * @param {Array} config.rows Array of record objects in which each object has a property for each field. 897 * The row data array must include all column values except for the primary key column. 898 * However, you will need to include the primary key column values if you defined 899 * them yourself instead of relying on auto-number. 900 * @param {Object} [config.extraContext] <b>Experimental:</b> Optional extra context object passed into the transformation/validation script environment. 901 * @param {Function} config.success Function called when the "insertRows" function executes successfully. 902 Will be called with the following arguments: 903 the parsed response data ({@link LABKEY.Query.ModifyRowsResults}), the XMLHttpRequest object and 904 (optionally) the "options" object ({@link LABKEY.Query.ModifyRowsOptions}). 905 * @param {Function} [config.failure] Function called when execution of the "insertRows" function fails. 906 * See {@link LABKEY.Query.selectRows} for more information on the parameters passed to this function. 907 * @param {String} [config.containerPath] The container path in which the schema and query name are defined. 908 * If not supplied, the current container path will be used. 909 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 910 * generating a timeout error (defaults to 30000). 911 * @param {boolean} [config.transacted] Whether all of the inserts should be done in a single transaction, so they all succeed or all fail. Defaults to true 912 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 913 * @returns {Mixed} In client-side scripts, this method will return a transaction id 914 * for the async request that can be used to cancel the request 915 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 916 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 917 * @example Example, from the Reagent Request <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=reagentRequestForm">Tutorial</a> and <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=reagentRequest">Demo</a>: <pre name="code" class="xml"> 918 // This snippet inserts data from the ReagentReqForm into a list. 919 // Upon success, it moves the user to the confirmation page and 920 // passes the current user's ID to that page. 921 LABKEY.Query.insertRows({ 922 containerPath: '/home/Study/demo/guestaccess', 923 schemaName: 'lists', 924 queryName: 'Reagent Requests', 925 rows: [{ 926 "Name": ReagentReqForm.DisplayName.value, 927 "Email": ReagentReqForm.Email.value, 928 "UserID": ReagentReqForm.UserID.value, 929 "Reagent": ReagentReqForm.Reagent.value, 930 "Quantity": parseInt(ReagentReqForm.Quantity.value), 931 "Date": new Date(), 932 "Comments": ReagentReqForm.Comments.value, 933 "Fulfilled": 'false' 934 }], 935 successCallback: function(data){ 936 window.location = 937 '/wiki/home/Study/demo/page.view?name=confirmation&userid=' 938 + LABKEY.Security.currentUser.id; 939 }, 940 }); </pre> 941 * @see LABKEY.Query.ModifyRowsResults 942 * @see LABKEY.Query.ModifyRowsOptions 943 */ 944 insertRows : function(config) 945 { 946 if (arguments.length > 1) 947 config = configFromArgs(arguments); 948 config.action = "insertRows.api"; 949 return sendJsonQueryRequest(config); 950 }, 951 952 /** 953 * Delete rows. 954 * @param {Object} config An object which contains the following configuration properties. 955 * @param {String} config.schemaName Name of a schema defined within the current container. See also: <a class="link" 956 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 957 How To Find schemaName, queryName & viewName</a>. 958 * @param {String} config.queryName Name of a query table associated with the chosen schema. See also: <a class="link" 959 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 960 How To Find schemaName, queryName & viewName</a>. 961 * @param {Object} [config.extraContext] <b>Experimental:</b> Optional extra context object passed into the transformation/validation script environment. 962 * @param {Function} config.success Function called when the "deleteRows" function executes successfully. 963 Will be called with the following arguments: 964 the parsed response data ({@link LABKEY.Query.ModifyRowsResults}), the XMLHttpRequest object and 965 (optionally) the "options" object ({@link LABKEY.Query.ModifyRowsOptions}). 966 * @param {Function} [config.failure] Function called when execution of the "deleteRows" function fails. 967 * See {@link LABKEY.Query.selectRows} for more information on the parameters passed to this function. 968 * @param {Array} config.rows Array of record objects in which each object has a property for each field. 969 * The row data array needs to include only the primary key column value, not all columns. 970 * @param {String} [config.containerPath] The container path in which the schema and query name are defined. 971 * If not supplied, the current container path will be used. 972 * @param {Integer} [config.timeout] The maximum number of milliseconds to allow for this operation before 973 * generating a timeout error (defaults to 30000). 974 * @param {boolean} [config.transacted] Whether all of the deletes should be done in a single transaction, so they all succeed or all fail. Defaults to true 975 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 976 * @returns {Mixed} In client-side scripts, this method will return a transaction id 977 * for the async request that can be used to cancel the request 978 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 979 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 980 * @see LABKEY.Query.ModifyRowsResults 981 * @see LABKEY.Query.ModifyRowsOptions 982 */ 983 deleteRows : function(config) 984 { 985 if (arguments.length > 1) 986 { 987 config = configFromArgs(arguments); 988 } 989 config.action = "deleteRows.api"; 990 return sendJsonQueryRequest(config); 991 }, 992 993 /** 994 * Delete a query view. 995 * @param config An object that contains the following configuration parameters 996 * @param {String} config.schemaName The name of the schema. 997 * @param {String} config.queryName the name of the query. 998 * @param {String} [config.viewName] the name of the view. If a viewName is not specified, the default view will be deleted/reverted. 999 * @param {boolean} [config.revert] Optionally, the view can be reverted instead of deleted. Defaults to false. 1000 */ 1001 deleteQueryView : function(config) { 1002 if (!config) { 1003 throw 'You must specify a configuration!' 1004 } 1005 if (!config.schemaName) { 1006 throw 'You must specify a schemaName!' 1007 } 1008 if (!config.queryName) { 1009 throw 'You must specify a queryName!' 1010 } 1011 1012 var params = { 1013 schemaName: config.schemaName, 1014 queryName: config.queryName 1015 }; 1016 1017 if (config.viewName) { 1018 params.viewName = config.viewName; 1019 } 1020 1021 if (config.revert !== undefined) { 1022 params.complete = config.revert !== true; 1023 } 1024 1025 return LABKEY.Ajax.request({ 1026 url: LABKEY.ActionURL.buildURL('query', 'deleteView.api', config.containerPath), 1027 method: 'POST', 1028 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1029 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1030 jsonData: params 1031 }); 1032 }, 1033 1034 /** 1035 * Build and return an object suitable for passing to the 1036 * <a href = "http://www.extjs.com/deploy/dev/docs/?class=Ext.Ajax">Ext.Ajax</a> 'params' configuration property. 1037 * @param {string} schemaName Name of a schema defined within the current container. See also: <a class="link" 1038 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 1039 How To Find schemaName, queryName & viewName</a>. 1040 * @param {string} queryName Name of a query table associated with the chosen schema. See also: <a class="link" 1041 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 1042 How To Find schemaName, queryName & viewName</a>. 1043 * @param {LABKEY.Filter[]} [filterArray] Array of objects created by {@link LABKEY.Filter.create}. 1044 * @param {string} [sort] String description of the sort. It includes the column names 1045 * listed in the URL of a sorted data region (with an optional minus prefix to indicate 1046 * descending order). In the case of a multi-column sort, up to three column names can be 1047 * included, separated by commas. 1048 * @param {string} [dataRegionName=query] 1049 * @returns {Object} Object suitable for passing to the 1050 * <a href = "http://extjs.com/deploy/ext-2.2.1/docs/?class=Ext.Ajax">Ext.Ajax</a> 'params' configuration property. 1051 */ 1052 buildQueryParams: function(schemaName, queryName, filterArray, sort, dataRegionName) 1053 { 1054 dataRegionName = dataRegionName || "query"; 1055 var params = {}; 1056 params.dataRegionName = dataRegionName; 1057 params[dataRegionName + '.queryName'] = queryName; 1058 params.schemaName = schemaName; 1059 if (sort) 1060 { 1061 params[dataRegionName + '.sort'] = sort; 1062 } 1063 1064 LABKEY.Filter.appendFilterParams(params, filterArray, dataRegionName); 1065 1066 return params; 1067 }, 1068 1069 /** 1070 * Returns the set of schemas available in the specified container. 1071 * @param config An object that contains the following configuration parameters 1072 * @param {String} config.schemaName Get schemas under the given schemaName. 1073 * @param {String} config.apiVersion Version of the API. Changed the structure of the server's response. 1074 * @param {function} config.success The function to call when the function finishes successfully. 1075 * This function will be called with the following parameters: 1076 * <ul> 1077 * <li><b>schemasInfo:</b> An object with a property called "schemas". If no apiVersion is specified, or it is 1078 * less than 9.3, it will be an array of schema names. If apiVersion is 9.3 or greater, it will be a map where 1079 * the keys are schemaNames and the values are objects with the following properties: 1080 * <ul> 1081 * <li><b>schemaName</b>: the short name of the schema</li> 1082 * <li><b>fullyQualifiedName</b>: the fully qualified name of the schema, encoded as a string with 1083 * "." separators as described in {@link LABKEY.SchemaKey}</li> 1084 * <li><b>description</b>: a short description of the schema</li> 1085 * <li><b>schemas</b>: a map of child schemas, with values in the same structure as this object</li> 1086 * </ul> 1087 * </li> 1088 * </ul> 1089 * @param {function} [config.failure] The function to call if this function encounters an error. 1090 * This function will be called with the following parameters: 1091 * <ul> 1092 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1093 * </ul> 1094 * @param {String} [config.containerPath] A container path in which to execute this command. If not supplied, 1095 * the current container will be used. 1096 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 1097 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1098 * for the async request that can be used to cancel the request 1099 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1100 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1101 */ 1102 getSchemas : function(config) 1103 { 1104 var params = {}; 1105 if (config.apiVersion) 1106 params.apiVersion = config.apiVersion; 1107 if (config.schemaName) 1108 params.schemaName = config.schemaName; 1109 1110 return LABKEY.Ajax.request({ 1111 url : LABKEY.ActionURL.buildURL('query', 'getSchemas.api', config.containerPath), 1112 method : 'GET', 1113 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1114 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1115 params: params 1116 }); 1117 }, 1118 1119 /** 1120 * Returns the set of queries available in a given schema. 1121 * @param config An object that contains the following configuration parameters 1122 * @param {String} config.schemaName The name of the schema. 1123 * @param {function} config.success The function to call when the function finishes successfully. 1124 * This function will be called with the following parameters: 1125 * <ul> 1126 * <li><b>queriesInfo:</b> An object with the following properties 1127 * <ul> 1128 * <li><b>schemaName:</b> the name of the requested schema</li> 1129 * <li><b>queries:</b> an array of objects, each of which has the following properties 1130 * <ul> 1131 * <li><b>name:</b> the name of the query</li> 1132 * <li><b>title:</b> this is the label used when displaying this table. If the table has no title, this will be the same as the name.</li> 1133 * <li><b>hidden:</b> true if this is a hidden query or table. 1134 * <li><b>inherit:</b> true if this query is marked as inheritable in sub-folders. 1135 * <li><b>isUserDefined:</b> true if this is a user-defined query</li> 1136 * <li><b>canEdit:</b> true if the current user can edit this query</li> 1137 * <li><b>isMetadataOverrideable:</b> true if the current user may override the query's metadata</li> 1138 * <li><b>moduleName:</b> the module that defines this query</li> 1139 * <li><b>isInherited:</b> true if this query is defined in a different container.</li> 1140 * <li><b>containerPath:</b> if <code>isInherited</code>, the container path where this query is defined.</li> 1141 * <li><b>description:</b> A description for this query (if provided)</li> 1142 * <li><b>viewDataUrl:</b> the server-relative URL where this query's data can be viewed. 1143 * Available in LabKey Server version 10.2 and later.</li> 1144 * <li><b>columns:</b> if config.includeColumns is not false, this will contain an array of 1145 * objects with the following properties 1146 * <ul> 1147 * <li><b>name:</b> the name of the column</li> 1148 * <li><b>caption:</b> the caption of the column (may be undefined)</li> 1149 * <li><b>description:</b> the description of the column (may be undefined)</li> 1150 * </ul> 1151 * </li> 1152 * </ul> 1153 * </li> 1154 * </ul> 1155 * </li> 1156 * </ul> 1157 * @param {function} [config.failure] The function to call if this function encounters an error. 1158 * This function will be called with the following parameters: 1159 * <ul> 1160 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1161 * </ul> 1162 * @param {Boolean} [config.includeUserQueries] If set to false, user-defined queries will not be included in 1163 * the results. Default is true. 1164 * @param {Boolean} [config.includeSystemQueries] If set to false, system-defined queries will not be included in 1165 * the results. Default is true. 1166 * @param {Boolean} [config.includeColumns] If set to false, information about the available columns in this 1167 * query will not be included in the results. Default is true. 1168 * @param {String} [config.containerPath] A container path in which to execute this command. If not supplied, 1169 * the current container will be used. 1170 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 1171 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1172 * for the async request that can be used to cancel the request 1173 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1174 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1175 */ 1176 getQueries : function(config) 1177 { 1178 var params = {}; 1179 // Only pass the parameters that the server supports, and exclude ones like successCallback 1180 LABKEY.Utils.applyTranslated(params, config, 1181 { 1182 schemaName: 'schemaName', 1183 includeColumns: 'includeColumns', 1184 includeUserQueries: 'includeUserQueries', 1185 includeSystemQueries: 'includeSystemQueries' 1186 }, false, false); 1187 1188 return LABKEY.Ajax.request({ 1189 url: LABKEY.ActionURL.buildURL('query', 'getQueries.api', config.containerPath), 1190 method : 'GET', 1191 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1192 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1193 params: params 1194 }); 1195 }, 1196 1197 /** 1198 * Returns the set of views available for a given query in a given schema. 1199 * @param config An object that contains the following configuration parameters 1200 * @param {String} config.schemaName The name of the schema. 1201 * @param {String} config.queryName the name of the query. 1202 * @param {String} [config.viewName] A view name (empty string for the default view), otherwise return all views for the query. 1203 * @param {Boolean} [config.metadata] Include view column field metadata. 1204 * @param {function} config.success The function to call when the function finishes successfully. 1205 * This function will be called with the following parameters: 1206 * <ul> 1207 * <li><b>viewsInfo:</b> An object with the following properties 1208 * <ul> 1209 * <li><b>schemaName:</b> the name of the requested schema</li> 1210 * <li><b>queryName:</b> the name of the requested query</li> 1211 * <li><b>views:</b> an array of objects, each of which has the following properties 1212 * <ul> 1213 * <li><b>name:</b> the name of the view (default view's name is empty string)</li> 1214 * <li><b>label:</b> the label of the view</li> 1215 * <li><b>default:</b> true if this is the default view info</li> 1216 * <li><b>viewDataUrl:</b> the server-relative URL where this view's data can be viewed. 1217 * Available in LabKey Server version 10.2 and later.</li> 1218 * <li><b>columns:</b> this will contain an array of objects with the following properties 1219 * <ul> 1220 * <li><b>name:</b> the name of the column</li> 1221 * <li><b>fieldKey:</b> the field key for the column (may include join column names, e.g. 'State/Population')</li> 1222 * </ul> 1223 * </li> 1224 * <li><b>filter:</b> TBD 1225 * Available in LabKey Server version 10.3 and later.</li> 1226 * <li><b>sort:</b> TBD 1227 * Available in LabKey Server version 10.3 and later.</li> 1228 * <li><b>fields:</b> TBD if metadata 1229 * Available in LabKey Server version 10.3 and later.</li> 1230 * </ul> 1231 * </li> 1232 * </ul> 1233 * </li> 1234 * </ul> 1235 * @param {function} [config.failure] The function to call if this function encounters an error. 1236 * This function will be called with the following parameters: 1237 * <ul> 1238 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1239 * </ul> 1240 * @param {String} [config.containerPath] A container path in which to execute this command. If not supplied, 1241 * the current container will be used. 1242 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 1243 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1244 * for the async request that can be used to cancel the request 1245 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1246 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1247 */ 1248 getQueryViews : function(config) 1249 { 1250 var params = {}; 1251 if (config.schemaName) 1252 params.schemaName = config.schemaName; 1253 if (config.queryName) 1254 params.queryName = config.queryName; 1255 if (config.viewName != undefined) 1256 params.viewName = config.viewName; 1257 if (config.metadata) 1258 params.metadata = config.metadata; 1259 1260 return LABKEY.Ajax.request({ 1261 url: LABKEY.ActionURL.buildURL('query', 'getQueryViews.api', config.containerPath), 1262 method : 'GET', 1263 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1264 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1265 params: params 1266 }); 1267 }, 1268 1269 /** 1270 * Creates or updates a custom view or views for a given query in a given schema. The config 1271 * object matches the viewInfos parameter of the getQueryViews.successCallback. 1272 * @param config An object that contains the following configuration parameters 1273 * @param {String} config.schemaName The name of the schema. 1274 * @param {String} config.queryName The name of the query. 1275 * @param {String} config.views The updated view definitions. 1276 * @param {function} config.success The function to call when the function finishes successfully. 1277 * This function will be called with the same parameters as getQueryViews.successCallback. 1278 * @param {function} [config.failure] The function to call if this function encounters an error. 1279 * This function will be called with the following parameters: 1280 * <ul> 1281 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1282 * </ul> 1283 * @param {String} [config.containerPath] A container path in which to execute this command. If not supplied, 1284 * the current container will be used. 1285 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 1286 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1287 * for the async request that can be used to cancel the request 1288 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1289 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1290 */ 1291 saveQueryViews : function (config) 1292 { 1293 var params = {}; 1294 if (config.schemaName) 1295 params.schemaName = config.schemaName; 1296 if (config.queryName) 1297 params.queryName = config.queryName; 1298 if (config.views) 1299 params.views = config.views; 1300 1301 return LABKEY.Ajax.request({ 1302 url: LABKEY.ActionURL.buildURL('query', 'saveQueryViews.api', config.containerPath), 1303 method: 'POST', 1304 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1305 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1306 jsonData : params, 1307 headers : { 1308 'Content-Type' : 'application/json' 1309 } 1310 }); 1311 }, 1312 1313 /** 1314 * Returns details about a given query including detailed information about result columns 1315 * @param {Object} config An object that contains the following configuration parameters 1316 * @param {String} config.schemaName The name of the schema. 1317 * @param {String} config.queryName The name of the query. 1318 * @param {String} [config.viewName] A view name or Array of view names to include custom view details. Use '*' to include all views for the query. 1319 * @param {String} [config.fields] A field key or Array of field keys to include in the metadata. 1320 * @param {Boolean} [config.initializeMissingView] Initialize the view based on the default view iff the view doesn't yet exist. 1321 * @param {function} config.success The function to call when the function finishes successfully. 1322 * This function will be called with the following parameters: 1323 * <ul> 1324 * <li><b>queryInfo:</b> An object with the following properties 1325 * <ul> 1326 * <li><b>schemaName:</b> the name of the requested schema</li> 1327 * <li><b>name:</b> the name of the requested query</li> 1328 * <li><b>isUserDefined:</b> true if this is a user-defined query</li> 1329 * <li><b>canEdit:</b> true if the current user can edit this query</li> 1330 * <li><b>isMetadataOverrideable:</b> true if the current user may override the query's metadata</li> 1331 * <li><b>moduleName:</b> the module that defines this query</li> 1332 * <li><b>isInherited:</b> true if this query is defined in a different container.</li> 1333 * <li><b>containerPath:</b> if <code>isInherited</code>, the container path where this query is defined.</li> 1334 * <li><b>viewDataUrl:</b> The URL to navigate to for viewing the data returned from this query</li> 1335 * <li><b>title:</b> If a value has been set, this is the label used when displaying this table</li> 1336 * <li><b>description:</b> A description for this query (if provided)</li> 1337 * <li><b>columns:</b> Information about all columns in this query. This is an array of LABKEY.Query.FieldMetaData objects.</li> 1338 * <li><b>defaultView:</b> An array of column information for the columns in the current user's default view of this query. 1339 * The shape of each column info is the same as in the columns array.</li> 1340 * <li><b>views:</b> An array of view info (XXX: same as views.getQueryViews() 1341 * </ul> 1342 * </li> 1343 * </ul> 1344 * @see LABKEY.Query.FieldMetaData 1345 * @param {function} [config.failure] The function to call if this function encounters an error. 1346 * This function will be called with the following parameters: 1347 * <ul> 1348 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1349 * </ul> 1350 * @param {String} [config.containerPath] A container path in which to execute this command. If not supplied, 1351 * the current container will be used. 1352 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 1353 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1354 * for the async request that can be used to cancel the request 1355 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1356 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1357 */ 1358 getQueryDetails : function(config) 1359 { 1360 var params = {}; 1361 if (config.schemaName) 1362 params.schemaName = config.schemaName; 1363 1364 if (config.queryName) 1365 params.queryName = config.queryName; 1366 1367 if (config.viewName != undefined) 1368 params.viewName = config.viewName; 1369 1370 if (config.fields) 1371 params.fields = config.fields; 1372 1373 if (config.fk) 1374 params.fk = config.fk; 1375 1376 if (config.initializeMissingView) 1377 params.initializeMissingView = config.initializeMissingView; 1378 1379 return LABKEY.Ajax.request({ 1380 url: LABKEY.ActionURL.buildURL('query', 'getQueryDetails.api', config.containerPath), 1381 method : 'GET', 1382 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1383 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1384 params: params 1385 }); 1386 }, 1387 1388 /** 1389 * Validates the specified query by ensuring that it parses and executes without an exception. 1390 * @param config An object that contains the following configuration parameters 1391 * @param {String} config.schemaName The name of the schema. 1392 * @param {String} config.queryName the name of the query. 1393 * @param {Boolean} config.includeAllColumns If set to false, only the columns in the user's default view 1394 * of the specific query will be tested (defaults to true). 1395 * @param {Boolean} config.validateQueryMetadata If true, the query metadata and custom views will also be validated. 1396 * @param {function} config.success The function to call when the function finishes successfully. 1397 * This function will be called with a simple object with one property named "valid" set to true. 1398 * @param {function} [config.failure] The function to call if this function encounters an error. 1399 * This function will be called with the following parameters: 1400 * <ul> 1401 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message. If validateQueryMetadata was used, this will also hae a property called 'errors', which is an array of objects describing each error.</li> 1402 * </ul> 1403 * @param {String} [config.containerPath] A container path in which to execute this command. If not supplied, 1404 * the current container will be used. 1405 * @param {Object} [config.scope] A scope for the callback functions. Defaults to "this" 1406 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1407 * for the async request that can be used to cancel the request 1408 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1409 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1410 */ 1411 validateQuery : function(config) 1412 { 1413 var params = {}; 1414 1415 LABKEY.Utils.applyTranslated(params, config, { 1416 successCallback: false, 1417 errorCallback: false, 1418 scope: false 1419 }); 1420 1421 return LABKEY.Ajax.request({ 1422 url: LABKEY.ActionURL.buildURL('query', (config.validateQueryMetadata ? 'validateQueryMetadata.api' : 'validateQuery.api'), config.containerPath), 1423 method : 'GET', 1424 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1425 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1426 params: params 1427 }); 1428 }, 1429 1430 /** 1431 * Returns the current date/time on the LabKey server. 1432 * @param config An object that contains the following configuration parameters 1433 * @param {function} config.success The function to call when the function finishes successfully. 1434 * This function will be called with a single parameter of type Date. 1435 * @param {function} [config.failure] The function to call if this function encounters an error. 1436 * This function will be called with the following parameters: 1437 * <ul> 1438 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1439 * </ul> 1440 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1441 * for the async request that can be used to cancel the request 1442 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1443 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1444 */ 1445 getServerDate : function(config) 1446 { 1447 return LABKEY.Ajax.request({ 1448 url: LABKEY.ActionURL.buildURL('query', 'getServerDate.api'), 1449 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope), 1450 success: LABKEY.Utils.getCallbackWrapper(function(json){ 1451 var d; 1452 var onSuccess = LABKEY.Utils.getOnSuccess(config); 1453 if (json && json.date && onSuccess) 1454 { 1455 d = new Date(json.date); 1456 onSuccess(d); 1457 } 1458 }, this) 1459 }); 1460 }, 1461 1462 1463 /** 1464 * Converts a javascript date into a format suitable for using in a LabKey SQL query, includes time but not milliseconds. 1465 * @param {Date} date JavaScript date 1466 * @param {Boolean} withMS include milliseconds 1467 * @returns {String} a date and time literal formatted to be used in a LabKey query 1468 */ 1469 sqlDateTimeLiteral : function(date, withMS) 1470 { 1471 if (date === undefined || date === null || !date) 1472 return "NULL"; 1473 if (typeof date == "string") 1474 { 1475 try { date = new Date(date); } catch (x) { } 1476 } 1477 if (typeof date == "object" && typeof date.toISOString == "function") 1478 { 1479 var fmt2 = function(a) {return (a>=10 ? ""+a : "0"+a);}; 1480 var fmt3 = function(a) {return (a>=100 ? ""+a : "0"+fmt2(a));}; 1481 return "{ts '" + 1482 date.getFullYear() + "-" + fmt2(date.getMonth()+1) + "-" +fmt2(date.getDate()) + " " + fmt2(date.getHours()) + ":" + fmt2(date.getMinutes()) + ":" + fmt2(date.getSeconds()) + 1483 (withMS ? "." + fmt3(date.getMilliseconds()) : "") 1484 + "'}"; 1485 } 1486 return "{ts '" + this.sqlStringLiteral(date) + "'}"; 1487 }, 1488 1489 1490 /** 1491 * Converts a JavaScript date into a format suitable for using in a LabKey SQL query, does not include time. 1492 * @param {Date} date JavaScript date 1493 * @returns {String} a date literal formatted to be used in a LabKey query 1494 */ 1495 sqlDateLiteral : function(date) 1496 { 1497 if (date === undefined || date === null || !date) 1498 return "NULL"; 1499 if (typeof date == "string") 1500 { 1501 try { date = new Date(date); } catch (x) { } 1502 } 1503 if (typeof date == "object" && typeof date.toISOString == "function") 1504 { 1505 var fmt2 = function(a) {return (a>=10 ? a : "0"+a);}; 1506 var fmt3 = function(a) {return (a>=999 ? a : "0"+fmt2(a));}; 1507 return "{d '" + 1508 date.getFullYear() + "-" + fmt2(date.getMonth()+1) + "-" +fmt2(date.getDate()) 1509 + "'}"; 1510 } 1511 return "{d '" + this.sqlStringLiteral(date) + "'}"; 1512 }, 1513 1514 1515 /** 1516 * Converts a JavaScript string into a format suitable for using in a LabKey SQL query. 1517 * @param {string} str String to use in query 1518 * @returns {string} value formatted for use in a LabKey query. Will properly escape single quote characters. 1519 */ 1520 sqlStringLiteral : function(str) 1521 { 1522 if (str === undefined || str === null || str == '') 1523 return "NULL"; 1524 str = str.toString(); 1525 return "'" + str.replace("'","''") + "'"; 1526 }, 1527 1528 URL_COLUMN_PREFIX: "_labkeyurl_" 1529 }; 1530 }; 1531 1532 /** 1533 * @class This class is used to construct filters when using APIs such as {@link LABKEY.Query.GetData.getRawData}, 1534 * {@link LABKEY.Query.selectRows}, or {@link LABKEY.Query.executeSql}. This is the base filter class, which requires 1535 * the user specify a filter type from {@link LABKEY.Filter#Types}. Users can avoid the need for specifying a filter 1536 * type by using a subclass of Filter such as {@link LABKEY.Query.Filter.Equals} or {@link LABKEY.Query.Filter.GreaterThan}, which 1537 * will automatically set the type for the user. 1538 * @param {String} columnName Required. The name of the column the filter will be applied Can be a string, array of strings, 1539 * or a {@link LABKEY.FieldKey} 1540 * @param value Value used as the filter criterion or an Array of values. 1541 * @param {LABKEY.Filter#Types} filterType Type of filter to apply to the 'column' using the 'value' 1542 * @constructor 1543 */ 1544 LABKEY.Query.Filter = function (columnName, value, filterType) 1545 { 1546 if (columnName) { 1547 if (columnName instanceof LABKEY.FieldKey) { 1548 columnName = columnName.toString(); 1549 } 1550 else if (columnName instanceof Array) { 1551 columnName = columnName.join('/'); 1552 } 1553 } 1554 1555 if (!filterType) 1556 { 1557 filterType = LABKEY.Filter.Types.EQUAL; 1558 } 1559 1560 /** 1561 * @private 1562 */ 1563 this.columnName = columnName; 1564 1565 /** 1566 * @private 1567 */ 1568 this.value = value; 1569 1570 /** 1571 * @private 1572 */ 1573 this.filterType = filterType; 1574 }; 1575 1576 /** 1577 * Gets the column name used in the filter. 1578 * @returns {String} 1579 */ 1580 LABKEY.Query.Filter.prototype.getColumnName = function () 1581 { 1582 return this.columnName 1583 }; 1584 1585 /** 1586 * Gets the filter type used to construct the filter. 1587 * @returns {LABKEY.Filter#Types} 1588 */ 1589 LABKEY.Query.Filter.prototype.getFilterType = function () 1590 { 1591 return this.filterType 1592 }; 1593 1594 /** 1595 * Returns the value of the filter. 1596 * @returns {*} 1597 */ 1598 LABKEY.Query.Filter.prototype.getValue = function () 1599 { 1600 return this.value 1601 }; 1602 1603 /** 1604 * Returns the value that will be put on URL. 1605 * @returns {String} 1606 */ 1607 LABKEY.Query.Filter.prototype.getURLParameterValue = function () 1608 { 1609 return this.filterType.isDataValueRequired() ? this.value : '' 1610 }; 1611 1612 /** 1613 * Returns the URL parameter name used for the filter. 1614 * @param dataRegionName The dataRegionName the filter is associated with. 1615 * @returns {String} 1616 */ 1617 LABKEY.Query.Filter.prototype.getURLParameterName = function (dataRegionName) 1618 { 1619 return (dataRegionName || "query") + "." + this.columnName + "~" + this.filterType.getURLSuffix(); 1620 }; 1621 1622 LABKEY.Query.Filter.HasAnyValue = function (columnName) 1623 { 1624 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.HAS_ANY_VALUE); 1625 }; 1626 LABKEY.Query.Filter.HasAnyValue.prototype = new LABKEY.Query.Filter; 1627 1628 /** 1629 * @class LABKEY.Query.Filter.Equal subclass of {@link LABKEY.Query.Filter}. 1630 * Finds rows where the column value matches the given filter value. Case-sensitivity depends upon how your 1631 * underlying relational database was configured. 1632 * @augments LABKEY.Query.Filter 1633 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1634 * or a {@link LABKEY.FieldKey} 1635 * @param value Value used as the filter criterion or an Array of values. 1636 * @constructor 1637 */ 1638 LABKEY.Query.Filter.Equal = function (columnName, value) 1639 { 1640 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.EQUAL); 1641 }; 1642 LABKEY.Query.Filter.Equal.prototype = new LABKEY.Query.Filter; 1643 1644 /** 1645 * @class LABKEY.Query.Filter.DateEqual subclass of {@link LABKEY.Query.Filter}. 1646 * Finds rows where the date portion of a datetime column matches the filter value (ignoring the time portion). 1647 * @augments LABKEY.Query.Filter 1648 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1649 * or a {@link LABKEY.FieldKey} 1650 * @param value Value used as the filter criterion or an Array of values. 1651 * @constructor 1652 */ 1653 LABKEY.Query.Filter.DateEqual = function (columnName, value) 1654 { 1655 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.DATE_EQUAL); 1656 }; 1657 LABKEY.Query.Filter.DateEqual.prototype = new LABKEY.Query.Filter; 1658 1659 /** 1660 * @class LABKEY.Query.Filter.DateNotEqual subclass of {@link LABKEY.Query.Filter}. 1661 * Finds rows where the date portion of a datetime column does not match the filter value (ignoring the time portion). 1662 * @augments LABKEY.Query.Filter 1663 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1664 * or a {@link LABKEY.FieldKey} 1665 * @param value Value used as the filter criterion or an Array of values. 1666 * @constructor 1667 */ 1668 LABKEY.Query.Filter.DateNotEqual = function (columnName, value) 1669 { 1670 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.DATE_NOT_EQUAL); 1671 }; 1672 LABKEY.Query.Filter.DateNotEqual.prototype = new LABKEY.Query.Filter; 1673 1674 /** 1675 * @class LABKEY.Query.Filter.NotEqualOrNull subclass of {@link LABKEY.Query.Filter}. 1676 * Finds rows where the column value does not equal the filter value, or is missing (null). 1677 * @augments LABKEY.Query.Filter 1678 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1679 * or a {@link LABKEY.FieldKey} 1680 * @param value Value used as the filter criterion or an Array of values. 1681 * @constructor 1682 */ 1683 LABKEY.Query.Filter.NotEqualOrNull = function (columnName, value) 1684 { 1685 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.NEQ_OR_NULL); 1686 }; 1687 LABKEY.Query.Filter.NotEqualOrNull.prototype = new LABKEY.Query.Filter; 1688 1689 /** 1690 * @class LABKEY.Query.Filter.NotEqualOrMissing subclass of {@link LABKEY.Query.Filter}. 1691 * Finds rows where the column value does not equal the filter value, or is missing (null). 1692 * @augments LABKEY.Query.Filter 1693 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1694 * or a {@link LABKEY.FieldKey} 1695 * @param value Value used as the filter criterion or an Array of values. 1696 * @constructor 1697 */ 1698 LABKEY.Query.Filter.NotEqualOrMissing = function (columnName, value) 1699 { 1700 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.NOT_EQUAL_OR_MISSING); 1701 }; 1702 LABKEY.Query.Filter.NotEqualOrMissing.prototype = new LABKEY.Query.Filter; 1703 1704 /** 1705 * @class LABKEY.Query.Filter.NotEqual subclass of {@link LABKEY.Query.Filter}. 1706 * Finds rows where the column value does not equal the filter value. 1707 * @augments LABKEY.Query.Filter 1708 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1709 * or a {@link LABKEY.FieldKey} 1710 * @param value Value used as the filter criterion or an Array of values. 1711 * @constructor 1712 */ 1713 LABKEY.Query.Filter.NotEqual = function (columnName, value) 1714 { 1715 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.NOT_EQUAL); 1716 }; 1717 LABKEY.Query.Filter.NotEqual.prototype = new LABKEY.Query.Filter; 1718 1719 /** 1720 * @class LABKEY.Query.Filter.Neq subclass of {@link LABKEY.Query.Filter}. 1721 * Finds rows where the column value does not equal the filter value. 1722 * @augments LABKEY.Query.Filter 1723 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1724 * or a {@link LABKEY.FieldKey} 1725 * @param value Value used as the filter criterion or an Array of values. 1726 * @constructor 1727 */ 1728 LABKEY.Query.Filter.Neq = function (columnName, value) 1729 { 1730 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.NEQ); 1731 }; 1732 LABKEY.Query.Filter.Neq.prototype = new LABKEY.Query.Filter; 1733 1734 /** 1735 * @class LABKEY.Query.Filter.Neq subclass of {@link LABKEY.Query.Filter}. 1736 * Finds rows where the column value is blank. 1737 * @augments LABKEY.Query.Filter 1738 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1739 * or a {@link LABKEY.FieldKey} 1740 * @constructor 1741 */ 1742 LABKEY.Query.Filter.IsBlank = function (columnName) 1743 { 1744 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.ISBLANK); 1745 }; 1746 LABKEY.Query.Filter.IsBlank.prototype = new LABKEY.Query.Filter; 1747 1748 /** 1749 * @class LABKEY.Query.Filter.Missing subclass of {@link LABKEY.Query.Filter}. 1750 * Finds rows where the column value is missing (null). Note that no filter value is required with this operator. 1751 * @augments LABKEY.Query.Filter 1752 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1753 * or a {@link LABKEY.FieldKey} 1754 * @constructor 1755 */ 1756 LABKEY.Query.Filter.Missing = function (columnName) 1757 { 1758 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.MISSING); 1759 }; 1760 LABKEY.Query.Filter.Missing.prototype = new LABKEY.Query.Filter; 1761 1762 /** 1763 * @class LABKEY.Query.Filter.NonBlank subclass of {@link LABKEY.Query.Filter}. 1764 * Finds rows where the column value is not blank. 1765 * @augments LABKEY.Query.Filter 1766 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1767 * or a {@link LABKEY.FieldKey} 1768 * @constructor 1769 */ 1770 LABKEY.Query.Filter.NonBlank = function (columnName) 1771 { 1772 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.NONBLANK); 1773 }; 1774 LABKEY.Query.Filter.NonBlank.prototype = new LABKEY.Query.Filter; 1775 1776 /** 1777 * @class LABKEY.Query.Filter.NotMissing subclass of {@link LABKEY.Query.Filter}. 1778 * Finds rows where the column value is not missing. 1779 * @augments LABKEY.Query.Filter 1780 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1781 * or a {@link LABKEY.FieldKey} 1782 * @constructor 1783 */ 1784 LABKEY.Query.Filter.NotMissing = function (columnName) 1785 { 1786 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.NOT_MISSING); 1787 }; 1788 LABKEY.Query.Filter.NotMissing.prototype = new LABKEY.Query.Filter; 1789 1790 /** 1791 * @class LABKEY.Query.Filter.Gt subclass of {@link LABKEY.Query.Filter}. 1792 * Finds rows where the column value is greater than the filter value. 1793 * @augments LABKEY.Query.Filter 1794 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1795 * or a {@link LABKEY.FieldKey} 1796 * @param value Value used as the filter criterion or an Array of values. 1797 * @constructor 1798 */ 1799 LABKEY.Query.Filter.Gt = function (columnName, value) 1800 { 1801 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.GT); 1802 }; 1803 LABKEY.Query.Filter.Gt.prototype = new LABKEY.Query.Filter; 1804 1805 /** 1806 * @class LABKEY.Query.Filter.GreaterThan subclass of {@link LABKEY.Query.Filter}. 1807 * Finds rows where the column value is greater than the filter value. 1808 * @augments LABKEY.Query.Filter 1809 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1810 * or a {@link LABKEY.FieldKey} 1811 * @param value Value used as the filter criterion or an Array of values. 1812 * @constructor 1813 */ 1814 LABKEY.Query.Filter.GreaterThan = function (columnName, value) 1815 { 1816 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.GREATER_THAN); 1817 }; 1818 LABKEY.Query.Filter.GreaterThan.prototype = new LABKEY.Query.Filter; 1819 1820 /** 1821 * @class LABKEY.Query.Filter.Lt subclass of {@link LABKEY.Query.Filter}. 1822 * Finds rows where the column value is less than the filter value. 1823 * @augments LABKEY.Query.Filter 1824 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1825 * or a {@link LABKEY.FieldKey} 1826 * @param value Value used as the filter criterion or an Array of values. 1827 * @constructor 1828 */ 1829 LABKEY.Query.Filter.Lt = function (columnName, value) 1830 { 1831 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.LT); 1832 }; 1833 LABKEY.Query.Filter.Lt.prototype = new LABKEY.Query.Filter; 1834 1835 /** 1836 * @class LABKEY.Query.Filter.LessThan subclass of {@link LABKEY.Query.Filter}. 1837 * Finds rows where the column value is less than the filter value. 1838 * @augments LABKEY.Query.Filter 1839 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1840 * or a {@link LABKEY.FieldKey} 1841 * @param value Value used as the filter criterion or an Array of values. 1842 * @constructor 1843 */ 1844 LABKEY.Query.Filter.LessThan = function (columnName, value) 1845 { 1846 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.LESS_THAN); 1847 }; 1848 LABKEY.Query.Filter.LessThan.prototype = new LABKEY.Query.Filter; 1849 1850 /** 1851 * @class LABKEY.Query.Filter.DateLessThan subclass of {@link LABKEY.Query.Filter}. 1852 * Finds rows where the date portion of a datetime column is less than the filter value (ignoring the time portion). 1853 * @augments LABKEY.Query.Filter 1854 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1855 * or a {@link LABKEY.FieldKey} 1856 * @param value Value used as the filter criterion or an Array of values. 1857 * @constructor 1858 */ 1859 LABKEY.Query.Filter.DateLessThan = function (columnName, value) 1860 { 1861 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.DATE_LESS_THAN); 1862 }; 1863 LABKEY.Query.Filter.DateLessThan.prototype = new LABKEY.Query.Filter; 1864 1865 /** 1866 * @class LABKEY.Query.Filter.Gte subclass of {@link LABKEY.Query.Filter}. 1867 * Finds rows where the column value is greater than or equal to the filter value. 1868 * @augments LABKEY.Query.Filter 1869 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1870 * or a {@link LABKEY.FieldKey} 1871 * @param value Value used as the filter criterion or an Array of values. 1872 * @constructor 1873 */ 1874 LABKEY.Query.Filter.Gte = function (columnName, value) 1875 { 1876 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.GTE); 1877 }; 1878 LABKEY.Query.Filter.Gte.prototype = new LABKEY.Query.Filter; 1879 1880 /** 1881 * @class LABKEY.Query.Filter.GreaterThanOrEqual subclass of {@link LABKEY.Query.Filter}. 1882 * Finds rows where the column value is greater than or equal to the filter value. 1883 * @augments LABKEY.Query.Filter 1884 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1885 * or a {@link LABKEY.FieldKey} 1886 * @param value Value used as the filter criterion or an Array of values. 1887 * @constructor 1888 */ 1889 LABKEY.Query.Filter.GreaterThanOrEqual = function (columnName, value) 1890 { 1891 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.GREATER_THAN_OR_EQUAL); 1892 }; 1893 LABKEY.Query.Filter.GreaterThanOrEqual.prototype = new LABKEY.Query.Filter; 1894 1895 /** 1896 * @class LABKEY.Query.Filter.GreaterThanOrEqual subclass of {@link LABKEY.Query.Filter}. 1897 * Finds rows where the date portion of a datetime column is greater than or equal to the filter value 1898 * (ignoring the time portion). 1899 * @augments LABKEY.Query.Filter 1900 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1901 * or a {@link LABKEY.FieldKey} 1902 * @param value Value used as the filter criterion or an Array of values. 1903 * @constructor 1904 */ 1905 LABKEY.Query.Filter.DateGreaterThanOrEqual = function (columnName, value) 1906 { 1907 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.DATE_GREATER_THAN_OR_EQUAL); 1908 }; 1909 LABKEY.Query.Filter.DateGreaterThanOrEqual.prototype = new LABKEY.Query.Filter; 1910 1911 /** 1912 * @class LABKEY.Query.Filter.Lte subclass of {@link LABKEY.Query.Filter}. 1913 * Finds rows where the column value is less than or equal to the filter value. 1914 * @augments LABKEY.Query.Filter 1915 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1916 * or a {@link LABKEY.FieldKey} 1917 * @param value Value used as the filter criterion or an Array of values. 1918 * @constructor 1919 */ 1920 LABKEY.Query.Filter.Lte = function (columnName, value) 1921 { 1922 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.LTE); 1923 }; 1924 LABKEY.Query.Filter.Lte.prototype = new LABKEY.Query.Filter; 1925 1926 /** 1927 * @class LABKEY.Query.Filter.LessThanOrEqual subclass of {@link LABKEY.Query.Filter}. 1928 * Finds rows where the column value is less than or equal to the filter value. 1929 * @augments LABKEY.Query.Filter 1930 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1931 * or a {@link LABKEY.FieldKey} 1932 * @param value Value used as the filter criterion or an Array of values. 1933 * @constructor 1934 */ 1935 LABKEY.Query.Filter.LessThanOrEqual = function (columnName, value) 1936 { 1937 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.LESS_THAN_OR_EQUAL); 1938 }; 1939 LABKEY.Query.Filter.LessThanOrEqual.prototype = new LABKEY.Query.Filter; 1940 1941 /** 1942 * @class LABKEY.Query.Filter.DateLessThanOrEqual subclass of {@link LABKEY.Query.Filter}. 1943 * Finds rows where the date portion of a datetime column is less than or equal to the filter value 1944 * (ignoring the time portion). 1945 * @augments LABKEY.Query.Filter 1946 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1947 * or a {@link LABKEY.FieldKey} 1948 * @param value Value used as the filter criterion or an Array of values. 1949 * @constructor 1950 */ 1951 LABKEY.Query.Filter.DateLessThanOrEqual = function (columnName, value) 1952 { 1953 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.DATE_LESS_THAN_OR_EQUAL); 1954 }; 1955 LABKEY.Query.Filter.DateLessThanOrEqual.prototype = new LABKEY.Query.Filter; 1956 1957 /** 1958 * @class LABKEY.Query.Filter.Contains subclass of {@link LABKEY.Query.Filter}. 1959 * Finds rows where the column value contains the filter value. Note that this may result in a slow query as this 1960 * cannot use indexes. 1961 * @augments LABKEY.Query.Filter 1962 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1963 * or a {@link LABKEY.FieldKey} 1964 * @param value Value used as the filter criterion or an Array of values. 1965 * @constructor 1966 */ 1967 LABKEY.Query.Filter.Contains = function (columnName, value) 1968 { 1969 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.CONTAINS); 1970 }; 1971 LABKEY.Query.Filter.Contains.prototype = new LABKEY.Query.Filter; 1972 1973 /** 1974 * @class LABKEY.Query.Filter.DoesNotContain subclass of {@link LABKEY.Query.Filter}. 1975 * Finds rows where the column value does not contain the filter value. Note that this may result in a slow query 1976 * as this cannot use indexes. 1977 * @augments LABKEY.Query.Filter 1978 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1979 * or a {@link LABKEY.FieldKey} 1980 * @param value Value used as the filter criterion or an Array of values. 1981 * @constructor 1982 */ 1983 LABKEY.Query.Filter.DoesNotContain = function (columnName, value) 1984 { 1985 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.DOES_NOT_CONTAIN); 1986 }; 1987 LABKEY.Query.Filter.DoesNotContain.prototype = new LABKEY.Query.Filter; 1988 1989 /** 1990 * @class LABKEY.Query.Filter.StartsWith subclass of {@link LABKEY.Query.Filter}. 1991 * Finds rows where the column value starts with the filter value. 1992 * @augments LABKEY.Query.Filter 1993 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 1994 * or a {@link LABKEY.FieldKey} 1995 * @param value Value used as the filter criterion or an Array of values. 1996 * @constructor 1997 */ 1998 LABKEY.Query.Filter.StartsWith = function (columnName, value) 1999 { 2000 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.STARTS_WITH); 2001 }; 2002 LABKEY.Query.Filter.StartsWith.prototype = new LABKEY.Query.Filter; 2003 2004 /** 2005 * @class LABKEY.Query.Filter.In subclass of {@link LABKEY.Query.Filter}. 2006 * Finds rows where the column value equals one of the supplied filter values. The values should be supplied as a 2007 * semi-colon-delimited list (example usage: a;b;c). 2008 * @augments LABKEY.Query.Filter 2009 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2010 * or a {@link LABKEY.FieldKey} 2011 * @param value Value used as the filter criterion or an Array of values. 2012 * @constructor 2013 */ 2014 LABKEY.Query.Filter.In = function (columnName, value) 2015 { 2016 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.IN); 2017 }; 2018 LABKEY.Query.Filter.In.prototype = new LABKEY.Query.Filter; 2019 2020 /** 2021 * @class LABKEY.Query.Filter.EqualsOneOf subclass of {@link LABKEY.Query.Filter}. 2022 * Finds rows where the column value equals one of the supplied filter values. The values should be supplied as a 2023 * semi-colon-delimited list (example usage: a;b;c). 2024 * @augments LABKEY.Query.Filter 2025 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2026 * or a {@link LABKEY.FieldKey} 2027 * @param value Value used as the filter criterion or an Array of values. 2028 * @constructor 2029 */ 2030 LABKEY.Query.Filter.EqualsOneOf = function (columnName, value) 2031 { 2032 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.EQUALS_ONE_OF); 2033 }; 2034 LABKEY.Query.Filter.EqualsOneOf.prototype = new LABKEY.Query.Filter; 2035 2036 /** 2037 * @class LABKEY.Query.Filter.EqualsNoneOf subclass of {@link LABKEY.Query.Filter}. 2038 * Finds rows where the column value does not equal one of the supplied filter values. The values should be supplied as a 2039 * semi-colon-delimited list (example usage: a;b;c). 2040 * @augments LABKEY.Query.Filter 2041 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2042 * or a {@link LABKEY.FieldKey} 2043 * @param value Value used as the filter criterion or an Array of values. 2044 * @constructor 2045 */ 2046 LABKEY.Query.Filter.EqualsNoneOf = function (columnName, value) 2047 { 2048 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.EQUALS_NONE_OF); 2049 }; 2050 LABKEY.Query.Filter.EqualsNoneOf.prototype = new LABKEY.Query.Filter; 2051 2052 /** 2053 * @class LABKEY.Query.Filter.NotIn subclass of {@link LABKEY.Query.Filter}. 2054 * Finds rows where the column value is not in any of the supplied filter values. The values should be supplied as 2055 * a semi-colon-delimited list (example usage: a;b;c). 2056 * @augments LABKEY.Query.Filter 2057 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2058 * or a {@link LABKEY.FieldKey} 2059 * @param value Value used as the filter criterion or an Array of values. 2060 * @constructor 2061 */ 2062 LABKEY.Query.Filter.NotIn = function (columnName, value) 2063 { 2064 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.NOT_IN); 2065 }; 2066 LABKEY.Query.Filter.NotIn.prototype = new LABKEY.Query.Filter; 2067 2068 /** 2069 * @class LABKEY.Query.Filter.ContainsOneOf subclass of {@link LABKEY.Query.Filter}. 2070 * Finds rows where the column value contains any of the supplied filter values. The values should be supplied as a 2071 * semi-colon-delimited list (example usage: a;b;c). 2072 * @augments LABKEY.Query.Filter 2073 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2074 * or a {@link LABKEY.FieldKey} 2075 * @param value Value used as the filter criterion or an Array of values. 2076 * @constructor 2077 */ 2078 LABKEY.Query.Filter.ContainsOneOf = function (columnName, value) 2079 { 2080 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.CONTAINS_ONE_OF); 2081 }; 2082 LABKEY.Query.Filter.ContainsOneOf.prototype = new LABKEY.Query.Filter; 2083 2084 /** 2085 * @class LABKEY.Query.Filter.MemberOf subclass of {@link LABKEY.Query.Filter}. 2086 * Finds rows where the column value corresponds to a user that is a member of a group with the id of the supplied filter value. 2087 * @augments LABKEY.Query.Filter 2088 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2089 * or a {@link LABKEY.FieldKey} 2090 * @param value Value used as the filter criterion. 2091 * @constructor 2092 */ 2093 LABKEY.Query.Filter.MemberOf = function (columnName, value) 2094 { 2095 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.MEMBER_OF); 2096 }; 2097 LABKEY.Query.Filter.ContainsOneOf.prototype = new LABKEY.Query.Filter; 2098 2099 /** 2100 * @class LABKEY.Query.Filter.ContainsNoneOf subclass of {@link LABKEY.Query.Filter}. 2101 * Finds rows where the column value does not contain any of the supplied filter values. The values should be supplied 2102 * as a semi-colon-delimited list (example usage: a;b;c). 2103 * @augments LABKEY.Query.Filter 2104 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2105 * or a {@link LABKEY.FieldKey} 2106 * @param value Value used as the filter criterion or an Array of values. 2107 * @constructor 2108 */ 2109 LABKEY.Query.Filter.ContainsNoneOf = function (columnName, value) 2110 { 2111 LABKEY.Query.Filter.call(this, columnName, value, LABKEY.Filter.Types.CONTAINS_NONE_OF); 2112 }; 2113 LABKEY.Query.Filter.ContainsNoneOf.prototype = new LABKEY.Query.Filter; 2114 2115 /** 2116 * @class LABKEY.Query.Filter.HasMissingValue subclass of {@link LABKEY.Query.Filter}. 2117 * Finds rows that have a missing value indicator. 2118 * @augments LABKEY.Query.Filter 2119 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2120 * or a {@link LABKEY.FieldKey} 2121 * @constructor 2122 */ 2123 LABKEY.Query.Filter.HasMissingValue = function (columnName) 2124 { 2125 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.HAS_MISSING_VALUE); 2126 }; 2127 LABKEY.Query.Filter.HasMissingValue.prototype = new LABKEY.Query.Filter; 2128 2129 /** 2130 * @class LABKEY.Query.Filter.DoesNotHaveMissingValue subclass of {@link LABKEY.Query.Filter}. 2131 * Finds rows that do not have a missing value indicator. 2132 * @augments LABKEY.Query.Filter 2133 * @param columnName Required. The name of the column the filter will be applied to. Can be a string, array of strings, 2134 * or a {@link LABKEY.FieldKey} 2135 * @constructor 2136 */ 2137 LABKEY.Query.Filter.DoesNotHaveMissingValue = function (columnName) 2138 { 2139 LABKEY.Query.Filter.call(this, columnName, null, LABKEY.Filter.Types.DOES_NOT_HAVE_MISSING_VALUE); 2140 }; 2141 LABKEY.Query.Filter.DoesNotHaveMissingValue.prototype = new LABKEY.Query.Filter; 2142 2143 (function(){ 2144 /** 2145 * @class LABKEY.Query.Row The class used to wrap each row object returned from the server during a GetData, executeSql, 2146 * or selectRows request. Most users will not instantiate these themselves. Instead they will interact with them during 2147 * the success handler of the API they are using. 2148 * @see LABKEY.Query.Response 2149 * @param row The raw row from a GetData or executeSQL, selectRows (version 13.2 and above) request. 2150 * @constructor 2151 */ 2152 LABKEY.Query.Row = function(row){ 2153 this.links = null; 2154 2155 if(row.links){ 2156 this.links = row.links; 2157 } 2158 2159 for (var attr in row.data) { 2160 if (row.data.hasOwnProperty(attr)) { 2161 this[attr] = row.data[attr]; 2162 } 2163 } 2164 }; 2165 2166 /** 2167 * Gets the requested column from the row. Includes extended values such as display value, URL, etc. 2168 * When requested version is >16.2, multi-value columns will return an array of objects containing "value" and other properties. 2169 * @param {String} columnName The column name requested. Used to do a case-insensitive match to find the column. 2170 * @returns {Object} For the given columnName, returns an object in the common case or an array of objects for multi-value columns. 2171 * The object will always contain a property named "value" that is the column's value, but it may also contain other properties about that column's value. For 2172 * example, if the column was setup to track missing value information, it will also contain a property named mvValue 2173 * (which is the raw value that is considered suspect), and a property named mvIndicator, which will be the string MV 2174 * indicator (e.g., "Q"). 2175 */ 2176 LABKEY.Query.Row.prototype.get = function(columnName){ 2177 columnName = columnName.toLowerCase(); 2178 2179 for (var attr in this) { 2180 if (attr.toLowerCase() === columnName && this.hasOwnProperty(attr) && !(this[attr] instanceof Function)) { 2181 return this[attr]; 2182 } 2183 } 2184 2185 return null; 2186 }; 2187 2188 /** 2189 * Gets the simple value for the requested column. Equivalent of doing Row.get(columnName).value. 2190 * For multi-value columns, the result is an array of values. 2191 * @param {String} columnName The column name requested. Used to do a case-insensitive match to find the column. 2192 * @returns {*} Returns the simple value for the given column. 2193 */ 2194 LABKEY.Query.Row.prototype.getValue = function(columnName){ 2195 columnName = columnName.toLowerCase(); 2196 2197 for (var attr in this) { 2198 if (attr.toLowerCase() === columnName && this.hasOwnProperty(attr) && !(this[attr] instanceof Function)) { 2199 if (LABKEY.Utils.isArray(this[attr])) { 2200 return this[attr].map(function (i) { return i.value; }); 2201 } 2202 if (this[attr].hasOwnProperty('value')) { 2203 return this[attr].value; 2204 } 2205 } 2206 } 2207 2208 return null; 2209 }; 2210 2211 /** 2212 * Gets all of the links for a row (details, update, etc.). 2213 * @returns {Object} Returns an object with all of the links types (details, update, etc.) for a row. 2214 */ 2215 LABKEY.Query.Row.prototype.getLinks = function(){ 2216 return this.links; 2217 }; 2218 2219 /** 2220 * Gets a specific link type for a row (details, update, etc.). 2221 * @param linkType Required. The name of the link type to be returned. 2222 * @returns {Object} Returns an object with the display text and link value. 2223 */ 2224 LABKEY.Query.Row.prototype.getLink = function(linkType){ 2225 if (this.links[linkType]) { 2226 return this.links[linkType]; 2227 } 2228 2229 return null; 2230 }; 2231 2232 /** 2233 * @private 2234 */ 2235 var generateColumnModel = function(fields) { 2236 var i, columns = []; 2237 2238 for (i = 0; i < fields.length; i++) { 2239 columns.push({ 2240 scale: fields[i].scale, 2241 hidden: fields[i].hidden, 2242 sortable: fields[i].sortable, 2243 align: fields[i].align, 2244 width: fields[i].width, 2245 dataIndex: fields[i].fieldKey.toString(), 2246 required: fields[i].nullable, // Not sure if this is correct. 2247 editable: fields[i].userEditable, 2248 header: fields[i].shortCaption 2249 }) 2250 } 2251 2252 return columns; 2253 }; 2254 2255 /** 2256 * @private 2257 */ 2258 var generateGetDisplayField = function(fieldKeyToFind, fields) { 2259 return function() { 2260 var fieldString = fieldKeyToFind.toString(); 2261 for (var i = 0; i < fields.length; i++) { 2262 if (fieldString == fields[i].fieldKey.toString()) { 2263 return fields[i]; 2264 } 2265 } 2266 return null; 2267 }; 2268 }; 2269 2270 /** 2271 * @class The class used to wrap the response object from {@link LABKEY.Query.GetData.getRawData}, 2272 * {@link LABKEY.Query.selectRows}, and {@link LABKEY.Query.executeSql}. 2273 * @param response The raw JSON response object returned from the server when executing {@link LABKEY.Query.GetData.getRawData}, 2274 * {@link LABKEY.Query.selectRows}, or {@link LABKEY.Query.executeSql} when requiredVersion is 13.2. 2275 * @see LABKEY.Query.GetData.getRawData 2276 * @see LABKEY.Query.selectRows 2277 * @see LABKEY.Query.executeSql 2278 * @constructor 2279 */ 2280 LABKEY.Query.Response = function(response) { 2281 // response = response; 2282 var i, attr; 2283 2284 // Shallow copy the response. 2285 for (attr in response) { 2286 if (response.hasOwnProperty(attr)) { 2287 this[attr] = response[attr]; 2288 } 2289 } 2290 2291 // Wrap the Schema, Lookup, and Field Keys. 2292 this.schemaKey = LABKEY.SchemaKey.fromParts(response.schemaName); 2293 2294 for (i = 0; i < response.metaData.fields.length; i++) { 2295 var field = response.metaData.fields[i], 2296 lookup = field.lookup; 2297 2298 field.fieldKey = LABKEY.FieldKey.fromParts(field.fieldKey); 2299 2300 if (lookup && lookup.schemaName) { 2301 lookup.schemaName = LABKEY.SchemaKey.fromParts(lookup.schemaName); 2302 } 2303 2304 if (field.displayField) { 2305 field.displayField = LABKEY.FieldKey.fromParts(field.displayField); 2306 field.getDisplayField = generateGetDisplayField(field.displayField, response.metaData.fields); 2307 } 2308 2309 // Only parse the 'extFormatFn' if ExtJS is present 2310 if (field.extFormatFn && window && (window.Ext !== undefined || window.Ext4 !== undefined)) { 2311 field.extFormatFn = eval(field.extFormatFn); 2312 } 2313 } 2314 2315 // Generate Column Model 2316 this.columnModel = generateColumnModel(this.metaData.fields); 2317 2318 // Wrap the rows -- may not be in the response (e.g. maxRows: 0) 2319 if (this.rows !== undefined) { 2320 for (i = 0; i < this.rows.length; i++) { 2321 this.rows[i] = new LABKEY.Query.Row(this.rows[i]); 2322 } 2323 } 2324 else { 2325 this.rows = []; 2326 } 2327 2328 return this; 2329 }; 2330 2331 /** 2332 * Gets the metaData object from the response. 2333 * @returns {Object} Returns an object with the following properties: 2334 * <ul> 2335 * <li><strong>fields</strong>: {Object[]} 2336 * Each field has the following properties: 2337 * <ul> 2338 * <li><strong>name</strong>: {String} The name of the field</li> 2339 * <li><strong>type</strong>: {String} JavaScript type name of the field</li> 2340 * <li><strong>shownInInsertView</strong>: {Boolean} whether this field is intended to be shown in insert views</li> 2341 * <li><strong>shownInUpdateView</strong>: {Boolean} whether this field is intended to be shown in update views</li> 2342 * <li><strong>shownInDetailsView</strong>: {Boolean} whether this field is intended to be shown in details views</li> 2343 * <li> 2344 * <strong>measure</strong>: {Boolean} whether this field is a measure. Measures are fields that contain data 2345 * subject to charting and other analysis. 2346 * </li> 2347 * <li> 2348 * <strong>dimension</strong>: {Boolean} whether this field is a dimension. Data dimensions define logical groupings 2349 * of measures. 2350 * </li> 2351 * <li><strong>hidden</strong>: {Boolean} whether this field is hidden and not normally shown in grid views</li> 2352 * <li><strong>lookup</strong>: {Object} If the field is a lookup, there will 2353 * be four sub-properties listed under this property: 2354 * schema, table, displayColumn, and keyColumn, which describe the schema, table, and 2355 * display column, and key column of the lookup table (query). 2356 * </li> 2357 * <li> 2358 * <strong>displayField</strong>: {{@link LABKEY.FieldKey}} If the field has a display field this is 2359 * the field key for that field. 2360 * </li> 2361 * <li> 2362 * <strong>getDisplayField</strong>: {Function} If the field has a display field this function will 2363 * return the metadata field object for that field. 2364 * </li> 2365 * </ul> 2366 * </li> 2367 * 2368 * <li><strong>id</strong>: Name of the primary key column.</li> 2369 * <li> 2370 * <strong>root</strong>: Name of the property containing rows ("rows"). This is mainly for the Ext 2371 * grid component. 2372 * </li> 2373 * <li><strong>title</strong>:</li> 2374 * <li> 2375 * <strong>totalProperty</strong>: Name of the top-level property containing the row count ("rowCount") in our case. 2376 * This is mainly for the Ext grid component. 2377 * </li> 2378 * </ul> 2379 */ 2380 LABKEY.Query.Response.prototype.getMetaData = function() { 2381 return this.metaData; 2382 }; 2383 2384 /** 2385 * Returns the schema name from the Response. 2386 * @param {Boolean} asString 2387 * @returns {*} If asString is true it returns a string, otherwise it returns a {@link LABKEY.FieldKey} object. 2388 */ 2389 LABKEY.Query.Response.prototype.getSchemaName = function(asString) { 2390 return asString ? this.schemaKey.toString() : this.schemaName; 2391 }; 2392 2393 /** 2394 * Returns the query name from the Response. 2395 * @returns {String} 2396 */ 2397 LABKEY.Query.Response.prototype.getQueryName = function() { 2398 return this.queryName; 2399 }; 2400 2401 /** 2402 * Returns an array of objects that can be used to assist in creating grids using ExtJs. 2403 * @returns {Array} Returns an array of Objects that can be used to assist in creating Ext Grids to 2404 * render the data. 2405 */ 2406 LABKEY.Query.Response.prototype.getColumnModel = function() { 2407 return this.columnModel; 2408 }; 2409 2410 /** 2411 * Returns the array of row objects. 2412 * @returns {Array} Returns an array of {@link LABKEY.Query.Row} objects. 2413 */ 2414 LABKEY.Query.Response.prototype.getRows = function() { 2415 return this.rows; 2416 }; 2417 2418 /** 2419 * Get a specific row from the row array. 2420 * @param {Integer} idx The index of the row you need. 2421 * @returns {LABKEY.Query.Row} 2422 */ 2423 LABKEY.Query.Response.prototype.getRow = function(idx) { 2424 if (this.rows[idx] !== undefined) { 2425 return this.rows[idx]; 2426 } 2427 2428 throw new Error('No row found for index ' + idx); 2429 }; 2430 2431 /** 2432 * Gets the row count from the response, which is the total number of rows in the query, not necessarily the number 2433 * of rows returned. For example, if setting maxRows to 100 on a query that has 5,000 rows, getRowCount will return 2434 * 5,000, not 100. 2435 * @returns {Integer} 2436 */ 2437 LABKEY.Query.Response.prototype.getRowCount = function() { 2438 return this.rowCount; 2439 }; 2440 })(); 2441 2442 /** 2443 * @name LABKEY.Query.ModifyRowsOptions 2444 * @class ModifyRowsOptions class to describe 2445 the third object passed to the successCallback function 2446 by {@link LABKEY.Query.updateRows}, {@link LABKEY.Query.insertRows} or 2447 {@link LABKEY.Query.deleteRows}. This object's properties are useful for 2448 matching requests to responses, as HTTP requests are typically 2449 processed asynchronously. 2450 * <p>Additional Documentation: 2451 * <ul> 2452 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2453 * How To Find schemaName, queryName & viewName</a></li> 2454 * </ul> 2455 * </p> 2456 * @see LABKEY.Query.updateRows 2457 * @see LABKEY.Query.insertRows 2458 * @see LABKEY.Query.deleteRows 2459 */ 2460 2461 /**#@+ 2462 * @memberOf LABKEY.Query.ModifyRowsOptions# 2463 * @field 2464 */ 2465 2466 /** 2467 * @name headers 2468 * @description An object containing one property for each HTTP header sent to the server. 2469 * @type Object 2470 */ 2471 2472 /** 2473 * @name method 2474 * @description The HTTP method used for the request (typically 'GET' or 'POST'). 2475 * @type String 2476 */ 2477 2478 /** 2479 * @name url 2480 * @description The URL that was requested. 2481 * @type String 2482 */ 2483 2484 /** 2485 * @name jsonData 2486 * @description The data object sent to the server. This will contain the following properties: 2487 <ul> 2488 <li><b>schemaName</b>: String. The schema name being modified. This is the same schemaName 2489 the client passed to the calling function. </li> 2490 <li><b>queryName</b>: String. The query name being modified. This is the same queryName 2491 the client passed to the calling function. </li> 2492 <li><b>rows</b>: Object[]. Array of row objects that map the names of the row fields to their values. 2493 The fields required for inclusion for each row depend on the which LABKEY.Query method you are 2494 using (updateRows, insertRows or deleteRows). </li> 2495 </ul> 2496 <p/> 2497 <b>For {@link LABKEY.Query.updateRows}:</b> <p/> 2498 For the 'updateRows' method, each row in the rows array must include its primary key value 2499 as one of its fields. 2500 <p/> 2501 An example of a ModifyRowsOptions object for the 'updateRows' successCallback: 2502 <pre name="code" class="xml"> 2503 {"schemaName": "lists", 2504 "queryName": "API Test List", 2505 "rows": [ 2506 {"Key": 1, 2507 "FirstName": "Z", 2508 "Age": "100"}] 2509 } </pre></code> 2510 2511 <p/> 2512 <b>For {@link LABKEY.Query.insertRows}:</b> <p/> 2513 For the 'insertRows' method, the fields of the rows should look the same as 2514 they do for the 'updateRows' method, except that primary key values for new rows 2515 need not be supplied if the primary key columns are auto-increment. 2516 <p/> 2517 An example of a ModifyRowsOptions object for the 'insertRows' successCallback: 2518 <pre name="code" class="xml"> 2519 {"schemaName": "lists", 2520 "queryName": "API Test List", 2521 "rows": [ 2522 {"FirstName": "C", 2523 "Age": "30"}] 2524 } </pre></code> 2525 2526 <p/> 2527 <b>For {@link LABKEY.Query.deleteRows}:</b> <p/> 2528 For the 'deleteRows' method, the fields of the rows should look the 2529 same as they do for the 'updateRows' method, except that the 'deleteRows' 2530 method needs to supply only the primary key values for the rows. All 2531 other row data will be ignored. 2532 <p/> 2533 An example of a ModifyRowsOptions object for the 'deleteRows' successCallback: 2534 <pre name="code" class="xml"> 2535 {"schemaName": "lists", 2536 "queryName": "API Test List", 2537 "rows": [ 2538 {"Key": 3}] 2539 } </pre></code> 2540 * @type Object 2541 */ 2542 2543 /**#@-*/ 2544 2545 /** 2546 * @name LABKEY.Query.ModifyRowsResults 2547 * @class ModifyRowsResults class to describe 2548 the first object passed to the successCallback function 2549 by {@link LABKEY.Query.updateRows}, {@link LABKEY.Query.insertRows} or 2550 {@link LABKEY.Query.deleteRows}. This object's properties are useful for 2551 matching requests to responses, as HTTP requests are typically 2552 processed asynchronously. 2553 * <p>Additional Documentation: 2554 * <ul> 2555 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2556 * How To Find schemaName, queryName & viewName</a></li> 2557 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=javascriptTutorial">LabKey JavaScript API Tutorial</a> and 2558 * <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=reagentRequest">Demo</a></li> 2559 * </ul> 2560 * </p> 2561 * @example For example: 2562 <pre name="code" class="xml"> 2563 { "schemaName": "lists", 2564 "queryName": "API Test List" 2565 "rowsAffected": 1, 2566 "command": "insert", 2567 "errors": [], 2568 "rows": [{ Key: 3, StringField: 'NewValue'}] 2569 } </pre></code> 2570 * @see LABKEY.Query.updateRows 2571 * @see LABKEY.Query.insertRows 2572 * @see LABKEY.Query.deleteRows 2573 * @see LABKEY.Query.saveRows 2574 */ 2575 2576 /**#@+ 2577 * @memberOf LABKEY.Query.ModifyRowsResults# 2578 * @field 2579 */ 2580 2581 /** 2582 * @name LABKEY.Query.ModifyRowsResults#schemaName 2583 * @description Contains the same schemaName the client passed to the calling function. 2584 * @type String 2585 */ 2586 2587 /** 2588 * @name LABKEY.Query.ModifyRowsResults#queryName 2589 * @description Contains the same queryName the client passed to the calling function. 2590 * @type String 2591 */ 2592 2593 /** 2594 * @name command 2595 * @description Will be "update", "insert", or "delete" depending on the API called. 2596 * @type String 2597 */ 2598 2599 /** 2600 * @name errors 2601 * @description Objects will contain the properties 'id' (the field to which the error is related, if any), 2602 * and 'msg' (the error message itself). 2603 * @type Array 2604 */ 2605 2606 /** 2607 * @name rowsAffected 2608 * @description Indicates the number of rows affected by the API action. 2609 This will typically be the same number of rows passed in to the calling function. 2610 * @type Integer 2611 */ 2612 2613 /** 2614 * @name LABKEY.Query.ModifyRowsResults#rows 2615 * @description Array of rows with field values for the rows updated, inserted, 2616 or deleted, in the same order as the rows supplied in the request. For insert, the 2617 new key value for an auto-increment key will be in the returned row's field values. 2618 For insert or update, the other field values may also be different than those supplied 2619 as a result of database default expressions, triggers, or LabKey's automatic tracking 2620 feature, which automatically adjusts columns of certain names (e.g., Created, CreatedBy, 2621 Modified, ModifiedBy, etc.). 2622 * @type Object[] 2623 */ 2624 2625 /**#@-*/ 2626 2627 /** 2628 * @name LABKEY.Query.SelectRowsOptions 2629 * @class SelectRowsOptions class to describe 2630 the third object passed to the successCallback function by 2631 {@link LABKEY.Query.selectRows}. This object's properties are useful for 2632 matching requests to responses, as HTTP requests are typically 2633 processed asynchronously. 2634 * <p>Additional Documentation: 2635 * <ul> 2636 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2637 * How To Find schemaName, queryName & viewName</a></li> 2638 * </ul> 2639 * </p> 2640 * @see LABKEY.Query.selectRows 2641 */ 2642 2643 /**#@+ 2644 * @memberOf LABKEY.Query.SelectRowsOptions# 2645 * @field 2646 */ 2647 2648 /** 2649 * @name query.schemaName 2650 * @description Contains the same schemaName the client passed to the 2651 calling function. See <a class="link" 2652 href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2653 How To Find schemaName, queryName & viewName</a>. 2654 * @type String 2655 */ 2656 2657 /** 2658 * @name query.queryName 2659 * @description Contains the same queryName the client passed 2660 to the calling function. See 2661 <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2662 How To Find schemaName, queryName & viewName</a>. 2663 * @type String 2664 */ 2665 2666 /** 2667 * @name query.viewName 2668 * @description Name of a valid custom view for the chosen queryName. See 2669 <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2670 How To Find schemaName, queryName & viewName</a>. 2671 * @type String 2672 */ 2673 2674 /** 2675 * @name query.offset 2676 * @description Row number at which results should begin. 2677 Use this with maxRows to get pages of results. 2678 * @type Integer 2679 */ 2680 2681 /** 2682 * @name query.sort 2683 * @description Sort specification. This can be a comma-delimited list of 2684 column names, where each column may have an optional dash (-) before the name 2685 to indicate a descending sort. 2686 * @type String 2687 */ 2688 2689 /** 2690 * @name maxRows 2691 * @description Maximum number of rows to return 2692 * @type Integer 2693 */ 2694 2695 /** 2696 * @name filters 2697 * @description An object whose properties are filter specifications, one for each filter you supplied. 2698 * All filters are combined using AND logic. Each one is of type {@link LABKEY.Filter.FilterDefinition}. 2699 * The list of valid operators: 2700 <ul><li><b>eq</b> = equals</li> 2701 <li><b>neq</b> = not equals</li> 2702 <li><b>gt</b> = greater-than</li> 2703 <li><b>gte</b> = greater-than or equal-to</li> 2704 <li><b>lt</b> = less-than</li> 2705 <li><b>lte</b> = less-than or equal-to</li> 2706 <li><b>dateeq</b> = date equal</li> 2707 <li><b>dateneq</b> = date not equal</li> 2708 <li><b>neqornull</b> = not equal or null</li> 2709 <li><b>isblank</b> = is null</li> 2710 <li><b>isnonblank</b> = is not null</li> 2711 <li><b>contains</b> = contains</li> 2712 <li><b>doesnotcontain</b> = does not contain</li> 2713 <li><b>startswith</b> = starts with</li> 2714 <li><b>doesnotstartwith</b> = does not start with</li> 2715 <li><b>in</b> = equals one of</li></ul> 2716 * @type Object 2717 */ 2718 2719 /**#@-*/ 2720 2721 /** 2722 * @name LABKEY.Query.FieldMetaDataLookup 2723 * @class Lookup metadata about a single field. 2724 * <p>Additional Documentation: 2725 * <ul> 2726 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2727 * How To Find schemaName, queryName & viewName</a></li> 2728 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=javascriptTutorial">LabKey JavaScript API Tutorial</a> and 2729 * <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=reagentRequest">Demo</a></li> 2730 * </ul> 2731 * </p> 2732 * @see LABKEY.Query.FieldMetaData 2733 */ 2734 2735 /**#@+ 2736 * @memberOf LABKEY.Query.FieldMetaDataLookup# 2737 * @field 2738 * @name containerPath 2739 * @description The path to the container that this lookup points to, if not the current container 2740 * @type String 2741 */ 2742 2743 /**#@+ 2744 * @memberOf LABKEY.Query.FieldMetaDataLookup# 2745 * @field 2746 * @name public 2747 * @description Whether the target of this lookup is exposed as a top-level query 2748 * @type boolean 2749 */ 2750 2751 /**#@+ 2752 * @memberOf LABKEY.Query.FieldMetaDataLookup# 2753 * @field 2754 * @name queryName 2755 * @description The name of the query that this lookup targets 2756 * @type String 2757 */ 2758 2759 /**#@+ 2760 * @memberOf LABKEY.Query.FieldMetaDataLookup# 2761 * @field 2762 * @name schemaName 2763 * @description The name of the schema that this lookup targets 2764 * @type String 2765 */ 2766 2767 /**#@+ 2768 * @memberOf LABKEY.Query.FieldMetaDataLookup# 2769 * @field 2770 * @name keyColumn 2771 * @description The name of column in the lookup's target that will be joined to the value in the local field 2772 * @type String 2773 */ 2774 2775 /**#@+ 2776 * @memberOf LABKEY.Query.FieldMetaDataLookup# 2777 * @field 2778 * @name displayColumn 2779 * @description The name of the column in the lookup's target that will be shown as its value, instead of the raw key value 2780 * @type String 2781 */ 2782 2783 /**#@-*/ 2784 2785 /** 2786 * @name LABKEY.Query.FieldMetaData 2787 * @class Metadata about a single field. 2788 * <p>Additional Documentation: 2789 * <ul> 2790 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 2791 * How To Find schemaName, queryName & viewName</a></li> 2792 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=javascriptTutorial">LabKey JavaScript API Tutorial</a> and 2793 * <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=reagentRequest">Demo</a></li> 2794 * </ul> 2795 * </p> 2796 * @see LABKEY.Query.selectRows 2797 * @see LABKEY.Query.getQueryDetails 2798 */ 2799 2800 /**#@+ 2801 * @memberOf LABKEY.Query.FieldMetaData# 2802 * @field 2803 * @name name 2804 * @description The name of the field 2805 * @type String 2806 */ 2807 2808 /**#@+ 2809 * @memberOf LABKEY.Query.FieldMetaData# 2810 * @field 2811 * @name friendlyType 2812 * @description A friendlier, more verbose description of the type, like "Text (String)" or "Date and Time" 2813 * @type String 2814 */ 2815 2816 /**#@+ 2817 * @memberOf LABKEY.Query.FieldMetaData# 2818 * @field 2819 * @name shownInInsertView 2820 * @description Whether this field is intended to be displayed in insert UIs 2821 * @type boolean 2822 */ 2823 2824 /**#@+ 2825 * @memberOf LABKEY.Query.FieldMetaData# 2826 * @field 2827 * @name shownInDetailView 2828 * @description Whether this field is intended to be displayed in detail UIs 2829 * @type boolean 2830 */ 2831 2832 /**#@+ 2833 * @memberOf LABKEY.Query.FieldMetaData# 2834 * @field 2835 * @name shownInUpdateView 2836 * @description Whether this field is intended to be displayed in update UIs 2837 * @type boolean 2838 */ 2839 2840 /**#@+ 2841 * @memberOf LABKEY.Query.FieldMetaData# 2842 * @field 2843 * @name versionField 2844 * @description Whether this field's value stores version information for the row 2845 * @type boolean 2846 */ 2847 2848 /**#@+ 2849 * @memberOf LABKEY.Query.FieldMetaData# 2850 * @field 2851 * @name userEditable 2852 * @description Whether this field is intended to be edited directly by the user, or managed by the system 2853 * @type boolean 2854 */ 2855 2856 /**#@+ 2857 * @memberOf LABKEY.Query.FieldMetaData# 2858 * @field 2859 * @name calculated 2860 * @description Whether this field is a calculated value such as something generated by a SQL expression, 2861 * or a "real"/"physical" column in the database 2862 * @type boolean 2863 */ 2864 2865 /**#@+ 2866 * @memberOf LABKEY.Query.FieldMetaData# 2867 * @field 2868 * @name readOnly 2869 * @description Whether the field's value can be modified 2870 * @type boolean 2871 */ 2872 2873 /**#@+ 2874 * @memberOf LABKEY.Query.FieldMetaData# 2875 * @field 2876 * @name nullable 2877 * @description Whether the field's value is allowed to be null 2878 * @type boolean 2879 */ 2880 2881 /**#@+ 2882 * @memberOf LABKEY.Query.FieldMetaData# 2883 * @field 2884 * @name mvEnabled 2885 * @description Whether this field supports missing value indicators instead of or addition to its standard value 2886 * @type boolean 2887 */ 2888 2889 /**#@+ 2890 * @memberOf LABKEY.Query.FieldMetaData# 2891 * @field 2892 * @name keyField 2893 * @description Whether this field is part of the row's primary key 2894 * @type boolean 2895 */ 2896 2897 /**#@+ 2898 * @memberOf LABKEY.Query.FieldMetaData# 2899 * @field 2900 * @name hidden 2901 * @description Whether this value is intended to be hidden from the user, especially for grid views 2902 * @type boolean 2903 */ 2904 2905 /**#@+ 2906 * @memberOf LABKEY.Query.FieldMetaData# 2907 * @field 2908 * @name autoIncrement 2909 * @description Whether this field's value is automatically assigned by the server, like a RowId whose value is determined by a database sequence 2910 * @type boolean 2911 */ 2912 2913 /**#@+ 2914 * @memberOf LABKEY.Query.FieldMetaData# 2915 * @field 2916 * @name jsonType 2917 * @description The type of JSON object that will represent this field's value: string, boolean, date, int, or float 2918 * @type String 2919 */ 2920 2921 /**#@+ 2922 * @memberOf LABKEY.Query.FieldMetaData# 2923 * @field 2924 * @name importAliases 2925 * @description Alternate names for this field that may appear in data when importing, whose values should be mapped to this field 2926 * @type String[] 2927 */ 2928 2929 /**#@+ 2930 * @memberOf LABKEY.Query.FieldMetaData# 2931 * @field 2932 * @name tsvFormat 2933 * @description The format string to be used for TSV exports 2934 * @type String 2935 */ 2936 2937 /**#@+ 2938 * @memberOf LABKEY.Query.FieldMetaData# 2939 * @field 2940 * @name format 2941 * @description The format string to be used for generating HTML 2942 * @type String 2943 */ 2944 2945 /**#@+ 2946 * @memberOf LABKEY.Query.FieldMetaData# 2947 * @field 2948 * @name excelFormat 2949 * @description The format string to be used for Excel exports 2950 * @type String 2951 */ 2952 2953 /**#@+ 2954 * @memberOf LABKEY.Query.FieldMetaData# 2955 * @field 2956 * @name extFormat 2957 * @description The format string that can be passed to Ext components. This is currently only supported for dates. 2958 * @type String 2959 */ 2960 2961 /**#@+ 2962 * @memberOf LABKEY.Query.FieldMetaData# 2963 * @field 2964 * @name extFormatFn 2965 * @description A function that can be used to produce the formatted string for this field. This is currently supported for dates and numeric values. 2966 * Note: this function is returned as a string, so you will need to evaluate it to convert it to a function. See example below. 2967 * @example <pre name="code" class="xml"> 2968 * var formatFn = eval(meta.extFormatFn); 2969 * var formattedValue = formatFn(data); 2970 * </pre></code> 2971 * 2972 * @type String 2973 */ 2974 2975 /**#@+ 2976 * @memberOf LABKEY.Query.FieldMetaData# 2977 * @field 2978 * @name caption 2979 * @description The caption to be shown for this field, typically in a column header, which may differ from its name 2980 * @type String 2981 */ 2982 2983 /**#@+ 2984 * @memberOf LABKEY.Query.FieldMetaData# 2985 * @field 2986 * @name shortCaption 2987 * @description The caption for this field, without any prefix from potential parent lookups. In many cases this will be identical to the caption property. 2988 * @type String 2989 */ 2990 2991 /**#@+ 2992 * @memberOf LABKEY.Query.FieldMetaData# 2993 * @field 2994 * @name description 2995 * @description The description for this field 2996 * @type String 2997 */ 2998 2999 /**#@+ 3000 * @memberOf LABKEY.Query.FieldMetaData# 3001 * @field 3002 * @name inputType 3003 * @description The type of form input to be used when editing this field, such as select, text, textarea, checkbox, or file 3004 * @type boolean 3005 */ 3006 3007 /**#@+ 3008 * @memberOf LABKEY.Query.FieldMetaData# 3009 * @field 3010 * @name lookup 3011 * @description Information about this field's lookup configuration 3012 * @type LABKEY.Query.FieldMetaDataLookup 3013 */ 3014 3015 /**#@-*/ 3016 3017 /** 3018 * @name LABKEY.Query.SelectRowsResults 3019 * @class SelectRowsResults class to describe the first 3020 object passed to the successCallback function by 3021 {@link LABKEY.Query.selectRows}. This object's properties are useful for 3022 matching requests to responses, as HTTP requests are typically 3023 processed asynchronously. 3024 * <p>Additional Documentation: 3025 * <ul> 3026 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 3027 * How To Find schemaName, queryName & viewName</a></li> 3028 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=javascriptTutorial">LabKey JavaScript API Tutorial</a> and 3029 * <a href="https://www.labkey.org/wiki/home/Study/demo/page.view?name=reagentRequest">Demo</a></li> 3030 * </ul> 3031 * </p> 3032 * @see LABKEY.Query.selectRows 3033 */ 3034 3035 /**#@+ 3036 * @memberOf LABKEY.Query.SelectRowsResults# 3037 * @field 3038 */ 3039 3040 /** 3041 * @name schemaName 3042 * @description the name of the resultset's source schema. 3043 * @type String 3044 */ 3045 3046 /** 3047 * @name queryName 3048 * @description the name of the resultset's source query. In some cases, such as an 'executeSql' call with 'saveInSession' set to true, the 3049 * query name may refer to temporary query that can be used to re-retrieve data for the duration of the user's session. 3050 * @type String 3051 */ 3052 3053 /** 3054 * @name metaData 3055 * @description Contains type and lookup information about the columns in the resultset. 3056 * @type Object 3057 */ 3058 3059 /** 3060 * @name metaData.root 3061 * @description Name of the property containing rows ("rows"). This is mainly for the Ext grid component. 3062 * @type String 3063 */ 3064 3065 /** 3066 * @name metaData.totalProperty 3067 * @description Name of the top-level property 3068 containing the row count ("rowCount") in our case. This is mainly 3069 for the Ext grid component. 3070 * @type String 3071 */ 3072 3073 /** 3074 * @name metaData.sortInfo 3075 * @description Sort specification in Ext grid terms. 3076 This contains two sub-properties, field and direction, which indicate 3077 the sort field and direction ("ASC" or "DESC") respectively. 3078 * @type Object 3079 */ 3080 3081 /** 3082 * @name metaData.id 3083 * @description Name of the primary key column. 3084 * @type String 3085 */ 3086 3087 /** 3088 * @name metaData.fields 3089 * @description Array of field information. 3090 * @type LABKEY.Query.FieldMetaData[] 3091 */ 3092 3093 /** 3094 * @name columnModel 3095 * @description Contains information about how one may interact 3096 with the columns within a user interface. This format is generated 3097 to match the requirements of the Ext grid component. See 3098 <a href="http://extjs.com/deploy/ext-2.2.1/docs/?class=Ext.grid.ColumnModel"> 3099 Ext.grid.ColumnModel</a> for further information. 3100 * @type Object[] 3101 */ 3102 3103 /** 3104 * @name rows 3105 * @description An array of rows, each of which is a 3106 sub-element/object containing a property per column. 3107 * @type Object[] 3108 */ 3109 3110 /** 3111 * @name rowCount 3112 * @description Indicates the number of total rows that could be 3113 returned by the query, which may be more than the number of objects 3114 in the rows array if the client supplied a value for the query.maxRows 3115 or query.offset parameters. This value is useful for clients that wish 3116 to display paging UI, such as the Ext grid. 3117 * @type Integer 3118 */ 3119 3120 /**#@-*/ 3121 3122 /** 3123 * @name LABKEY.Query.ExtendedSelectRowsResults 3124 * @class ExtendedSelectRowsResults class to describe the first 3125 object passed to the successCallback function by 3126 {@link LABKEY.Query.selectRows} if config.requiredVersion is set to "9.1". 3127 * <p>Additional Documentation: 3128 * <ul> 3129 * <li><a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=findNames"> 3130 * How To Find schemaName, queryName & viewName</a></li> 3131 * </ul> 3132 * </p> 3133 * @see LABKEY.Query.selectRows 3134 */ 3135 3136 /**#@+ 3137 * @memberOf LABKEY.Query.ExtendedSelectRowsResults# 3138 * @field 3139 */ 3140 3141 /** 3142 * @name LABKEY.Query.ExtendedSelectRowsResults#metaData 3143 * @description Contains type and lookup information about the columns in the resultset. 3144 * @type Object 3145 */ 3146 3147 /** 3148 * @name LABKEY.Query.ExtendedSelectRowsResults#metaData.root 3149 * @description Name of the property containing rows ("rows"). This is mainly for the Ext grid component. 3150 * @type String 3151 */ 3152 3153 /** 3154 * @name LABKEY.Query.ExtendedSelectRowsResults#metaData.totalProperty 3155 * @description Name of the top-level property 3156 containing the row count ("rowCount") in our case. This is mainly 3157 for the Ext grid component. 3158 * @type String 3159 */ 3160 3161 /** 3162 * @name LABKEY.Query.ExtendedSelectRowsResults#metaData.sortInfo 3163 * @description Sort specification in Ext grid terms. 3164 This contains two sub-properties, field and direction, which indicate 3165 the sort field and direction ("ASC" or "DESC") respectively. 3166 * @type Object 3167 */ 3168 3169 /** 3170 * @name LABKEY.Query.ExtendedSelectRowsResults#metaData.id 3171 * @description Name of the primary key column. 3172 * @type String 3173 */ 3174 3175 /** 3176 * @name LABKEY.Query.ExtendedSelectRowsResults#metaData.fields 3177 * @description Array of field information. 3178 Each field has the following properties: 3179 <ul><li><b>name</b> -- The name of the field</li> 3180 <li><b>type</b> -- JavaScript type name of the field</li> 3181 <li><b>shownInInsertView</b> -- whether this field is intended to be shown in insert views</li> 3182 <li><b>shownInUpdateView</b> -- whether this field is intended to be shown in update views</li> 3183 <li><b>shownInDetailsView</b> -- whether this field is intended to be shown in details views</li> 3184 <li><b>measure</b> -- whether this field is a measure. Measures are fields that contain data subject to charting and other analysis.</li> 3185 <li><b>dimension</b> -- whether this field is a dimension. Data dimensions define logical groupings of measures.</li> 3186 <li><b>hidden</b> -- whether this field is hidden and not normally shown in grid views</li> 3187 <li><b>lookup</b> -- If the field is a lookup, there will 3188 be four sub-properties listed under this property: 3189 schema, table, displayColumn, and keyColumn, which describe the schema, table, and 3190 display column, and key column of the lookup table (query).</li></ul> 3191 * @type Object[] 3192 */ 3193 3194 /** 3195 * @name LABKEY.Query.ExtendedSelectRowsResults#columnModel 3196 * @description Contains information about how one may interact 3197 with the columns within a user interface. This format is generated 3198 to match the requirements of the Ext grid component. See 3199 <a href="http://extjs.com/deploy/ext-2.2.1/docs/?class=Ext.grid.ColumnModel"> 3200 Ext.grid.ColumnModel</a> for further information. 3201 * @type String 3202 */ 3203 3204 /** 3205 * @name LABKEY.Query.ExtendedSelectRowsResults#rows 3206 * @description An array of rows, each of which is a 3207 sub-element/object containing an object per column. The 3208 object will always contain a property named "value" that is the 3209 column's value, but it may also contain other properties about 3210 that column's value. For example, if the column was setup to track 3211 missing value information, it will also contain a property named mvValue (which 3212 is the raw value that is considered suspect), and a property named 3213 mvIndicator, which will be the string MV indicator (e.g., "Q"). 3214 * @type Object[] 3215 */ 3216 3217 /** 3218 * @name LABKEY.Query.ExtendedSelectRowsResults#rowCount 3219 * @description Indicates the number of total rows that could be 3220 returned by the query, which may be more than the number of objects 3221 in the rows array if the client supplied a value for the query.maxRows 3222 or query.offset parameters. This value is useful for clients who wish 3223 to display paging UI, such as the Ext grid. 3224 * @type Integer 3225 */ 3226 3227 /**#@-*/ 3228 3229 /** docs for methods defined in dom/Query.js - primarily here to ensure API docs get generated with combined core/dom versions */ 3230 3231 /** 3232 * Execute arbitrary LabKey SQL and export the results to Excel or TSV. After this method is 3233 * called, the user will be prompted to accept a file from the server, and most browsers will allow 3234 * the user to either save it or open it in an apporpriate application. 3235 * For more information, see the 3236 * <a href="https://www.labkey.org/wiki/home/Documentation/page.view?name=labkeySql"> 3237 * LabKey SQL Reference</a>. 3238 * 3239 * @memberOf LABKEY.Query 3240 * @function 3241 * @static 3242 * @name exportSql 3243 * @param config An object which contains the following configuration properties. 3244 * @param {String} config.schemaName name of the schema to query. 3245 * @param {String} config.sql The LabKey SQL to execute. 3246 * @param {String} [config.format] The desired export format. May be either 'excel' or 'tsv'. Defaults to 'excel'. 3247 * @param {String} [config.containerPath] The path to the container in which the schema and query are defined, 3248 * if different than the current container. If not supplied, the current container's path will be used. 3249 * @param {String} [config.containerFilter] One of the values of {@link LABKEY.Query.containerFilter} that sets 3250 * the scope of this query. Defaults to containerFilter.current, and is interpreted relative to 3251 * config.containerPath. 3252 */ 3253