From bf04ab5ffc373b47262794cb41367e9005454f2c Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 23 Apr 2019 12:13:08 +0100 Subject: [PATCH] Update Xmla.js Added in a memory limit check on the response size, as we were getting browser crashes when the response was too big. --- src/Xmla.js | 16751 +++++++++++++++++++++++++------------------------- 1 file changed, 8386 insertions(+), 8365 deletions(-) diff --git a/src/Xmla.js b/src/Xmla.js index 84c4471..88edf5e 100644 --- a/src/Xmla.js +++ b/src/Xmla.js @@ -39,8509 +39,8530 @@ * @title Xmla */ (function(window) { -var Xmla, - _soap = "http://schemas.xmlsoap.org/soap/", - _xmlnsSOAPenvelope = _soap + "envelope/", - _xmlnsSOAPenvelopePrefix = "SOAP-ENV", - _xmlnsIsSOAPenvelope = "xmlns:" + _xmlnsSOAPenvelopePrefix + "=\"" + _xmlnsSOAPenvelope + "\"", - _SOAPencodingStyle = _xmlnsSOAPenvelopePrefix + ":encodingStyle=\"" + _soap + "encoding/\"", - _ms = "urn:schemas-microsoft-com:", - _xmlnsXmla = _ms + "xml-analysis", - _xmlnsIsXmla = "xmlns=\"" + _xmlnsXmla + "\"", - _xmlnsSQLPrefix = "sql", - _xmlnsSQL = _ms + "xml-sql", - _xmlnsSchema = "http://www.w3.org/2001/XMLSchema", - _xmlnsSchemaPrefix = "xsd", - _xmlnsSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance", - _xmlnsSchemaInstancePrefix = "xsi", - _xmlnsRowset = _xmlnsXmla + ":rowset", - _xmlnsDataset = _xmlnsXmla + ":mddataset" -; - -var _createXhr; -if (window.XMLHttpRequest) _createXhr = function(){ - return new window.XMLHttpRequest(); -} -else -if (window.ActiveXObject) _createXhr = function(){ - return new window.ActiveXObject("MSXML2.XMLHTTP.3.0"); -} -else -if (typeof(require)==="function") _createXhr = function(){ - var xhr; - (xhr = function() { - this.readyState = 0; - this.status = -1; - this.statusText = "Not sent"; - this.responseText = null; - }).prototype = { - changeStatus: function(statusCode, readyState){ - this.status = statusCode; - this.statusText = statusCode; - this.readyState = readyState; - if (_isFun(this.onreadystatechange)) { - this.onreadystatechange.call(this, this); - } - }, - open: function(method, url, async, username, password){ - if (async !== true) { - throw "Synchronous mode not supported in this environment." - } - var options = require("url").parse(url); - if (options.host.length > options.hostname.length) { - //for some reason, host includes the port, this confuses http.request - //so, overwrite host with hostname (which does not include the port) - //and kill hostname so that we end up with only host. - options.host = options.hostname; - delete options.hostname; - } - if (!options.path && options.pathname) { - //old versions of node may not give the path, so we need to create it ourselves. - options.path = options.pathname + (options.search || ""); - } - options.method = "POST";//method; - options.headers = {}; - if (username) { - options.headers.Authorization = "Basic " + (new Buffer(username + ":" + (password || ""))).toString("base64"); - } - this.options = options; - this.changeStatus(-1, 1); - }, - send: function(data){ - var me = this, - options = me.options, - client - ; - options.headers["Content-Length"] = Buffer.byteLength(data); - switch (options.protocol) { - case "http:": - client = require("http"); - if (!options.port) options.port = "80"; - break; - case "https:": - client = require("https"); - if (!options.port) options.port = "443"; - break; - default: - throw "Unsupported protocol " + options.protocol; - } - me.responseText = ""; - var request = client.request(options, function(response){ - response.setEncoding("utf8"); - me.changeStatus(-1, 2); - response.on("data", function(chunk){ - me.responseText += chunk; - me.changeStatus(response.statusCode, 3); + var Xmla, + _soap = "http://schemas.xmlsoap.org/soap/", + _xmlnsSOAPenvelope = _soap + "envelope/", + _xmlnsSOAPenvelopePrefix = "SOAP-ENV", + _xmlnsIsSOAPenvelope = "xmlns:" + _xmlnsSOAPenvelopePrefix + "=\"" + _xmlnsSOAPenvelope + "\"", + _SOAPencodingStyle = _xmlnsSOAPenvelopePrefix + ":encodingStyle=\"" + _soap + "encoding/\"", + _ms = "urn:schemas-microsoft-com:", + _xmlnsXmla = _ms + "xml-analysis", + _xmlnsIsXmla = "xmlns=\"" + _xmlnsXmla + "\"", + _xmlnsSQLPrefix = "sql", + _xmlnsSQL = _ms + "xml-sql", + _xmlnsSchema = "http://www.w3.org/2001/XMLSchema", + _xmlnsSchemaPrefix = "xsd", + _xmlnsSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance", + _xmlnsSchemaInstancePrefix = "xsi", + _xmlnsRowset = _xmlnsXmla + ":rowset", + _xmlnsDataset = _xmlnsXmla + ":mddataset" + ; + + var _createXhr; + if (window.XMLHttpRequest) _createXhr = function(){ + return new window.XMLHttpRequest(); + } + else + if (window.ActiveXObject) _createXhr = function(){ + return new window.ActiveXObject("MSXML2.XMLHTTP.3.0"); + } + else + if (typeof(require)==="function") _createXhr = function(){ + var xhr; + (xhr = function() { + this.readyState = 0; + this.status = -1; + this.statusText = "Not sent"; + this.responseText = null; + }).prototype = { + changeStatus: function(statusCode, readyState){ + this.status = statusCode; + this.statusText = statusCode; + this.readyState = readyState; + if (_isFun(this.onreadystatechange)) { + this.onreadystatechange.call(this, this); + } + }, + open: function(method, url, async, username, password){ + if (async !== true) { + throw "Synchronous mode not supported in this environment." + } + var options = require("url").parse(url); + if (options.host.length > options.hostname.length) { + //for some reason, host includes the port, this confuses http.request + //so, overwrite host with hostname (which does not include the port) + //and kill hostname so that we end up with only host. + options.host = options.hostname; + delete options.hostname; + } + if (!options.path && options.pathname) { + //old versions of node may not give the path, so we need to create it ourselves. + options.path = options.pathname + (options.search || ""); + } + options.method = "POST";//method; + options.headers = {}; + if (username) { + options.headers.Authorization = "Basic " + (new Buffer(username + ":" + (password || ""))).toString("base64"); + } + this.options = options; + this.changeStatus(-1, 1); + }, + send: function(data){ + var me = this, + options = me.options, + client + ; + options.headers["Content-Length"] = Buffer.byteLength(data); + switch (options.protocol) { + case "http:": + client = require("http"); + if (!options.port) options.port = "80"; + break; + case "https:": + client = require("https"); + if (!options.port) options.port = "443"; + break; + default: + throw "Unsupported protocol " + options.protocol; + } + me.responseText = ""; + var request = client.request(options, function(response){ + response.setEncoding("utf8"); + me.changeStatus(-1, 2); + response.on("data", function(chunk){ + me.responseText += chunk; + me.changeStatus(response.statusCode, 3); + }); + response.on("error", function(error){ + me.changeStatus(response.statusCode, 4); + }); + response.on("end", function(){ + me.changeStatus(response.statusCode, 4); + }); }); - response.on("error", function(error){ - me.changeStatus(response.statusCode, 4); + request.on("error", function(e){ + me.responseText = e; + me.changeStatus(500, 4); }); - response.on("end", function(){ - me.changeStatus(response.statusCode, 4); + /* does not work, maybe only not in old node versions. + request.setTimeout(this.timeout, function(){ + request.abort(); + me.changeStatus(500, 0); }); - }); - request.on("error", function(e){ - me.responseText = e; - me.changeStatus(500, 4); - }); - /* does not work, maybe only not in old node versions. - request.setTimeout(this.timeout, function(){ - request.abort(); - me.changeStatus(500, 0); - }); - */ - if (data) request.write(data); - request.end(); - }, - setRequestHeader: function(name, value){ - this.options.headers[name] = value; - } - }; - return new xhr(); -} -else Xmla.Exception._newError( - "ERROR_INSTANTIATING_XMLHTTPREQUEST", - "_ajax", - null -)._throw(); - - -function _ajax(options){ - var xhr, args, headers, header, - handlerCalled = false, - handler = function(){ - handlerCalled = true; - switch (xhr.readyState){ - case 0: - if (_isFun(options.aborted)) { - options.aborted(xhr); - } - break; - case 4: - //See https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0 - //Preflight request is acceptable if the HTTP status code is in the 2xx range - //Specifically, Windows IIS may return a 204 rather than a 200 code to the OPTIONS request - if (xhr.status >= 200 && xhr.status <= 299) { - options.complete(xhr) - } - else { - var err = Xmla.Exception._newError( - "HTTP_ERROR", - "_ajax", - { - request: options, - status: this.status, - statusText: this.statusText, - xhr: xhr - } - ) - //console.log(err); - //When I have an error in HTTP, this allows better debugging - //So made an extra call instead of _newError inside func call - options.error(err); - } - break; + */ + if (data) request.write(data); + request.end(); + }, + setRequestHeader: function(name, value){ + this.options.headers[name] = value; } }; - - xhr = _createXhr(); - args = ["POST", options.url, options.async]; - if (options.username && options.password) { - args = args.concat([options.username, options.password]); + return new xhr(); } - xhr.open.apply(xhr, args); + else Xmla.Exception._newError( + "ERROR_INSTANTIATING_XMLHTTPREQUEST", + "_ajax", + null + )._throw(); - //It is necessary for the XML HTTP Request to send credentials when IIS is in Windows Authentication mode, with Anonymous Authentication turned off and the Access-Control-Allow-Credentials header is set - //See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials - xhr.withCredentials = true; - //see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute - if (!_isUnd(options.requestTimeout) && (options.async || !(window && window.document))) { - xhr.timeout = options.requestTimeout; - } - xhr.onreadystatechange = handler; - xhr.setRequestHeader("Accept", "text/xml, application/xml, application/soap+xml"); - xhr.setRequestHeader("Content-Type", "text/xml"); - if (headers = options.headers) { - for (header in headers) { - xhr.setRequestHeader(header, headers[header]); - } - } - xhr.send(options.data); - if (!options.async && !handlerCalled) { - handler.call(xhr); - } - return xhr; -}; - -function _isUnd(arg){ - return typeof(arg)==="undefined"; -}; -function _isArr(arg){ - return arg && arg.constructor === Array; -}; -function _isNum(arg){ - return typeof(arg)==="number"; -}; -function _isFun(arg){ - return typeof(arg)==="function"; -}; -function _isStr(arg) { - return typeof(arg)==="string"; -}; -function _isObj(arg) { - return arg && typeof(arg)==="object"; -}; -function _xmlEncode(value){ - var value; - switch (typeof(value)) { - case "string": - value = value.replace(/\&/g, "&").replace(//g, ">"); - break; - case "undefined": - value = ""; - break; - case "object": - if (value === null) { - value = ""; - } - } - return value; -}; - -function _decodeXmlaTagName(tagName) { - return tagName.replace(/_x(\d\d\d\d)_/g, function(match, hex, offset){ - return String.fromCharCode(parseInt(hex, 16)); - }); -} -//this is here to support (partial) dom interface on top of our own document implementation -//we don't need this in the browser, it's here when running in environments without a native xhr -//where the xhr object does not offer a DOM responseXML object. -function _getElements(parent, list, criteria){ - var childNodes = parent.childNodes; - if (!childNodes) return list; - for (var node, i = 0, n = childNodes.length; i < n; i++){ - node = childNodes[i]; - if (criteria && criteria.call(null, node) === true) list.push(node); - _getElements(node, list, criteria); - } -}; - -var _getElementsByTagName = function(node, tagName){ - var func; - if ("getElementsByTagName" in node) { - func = function(node, tagName) { - return node.getElementsByTagName(tagName); - }; - } - else { - var checkCriteria = function(node){ - if (node.nodeType !== 1) { - return false; - } - var nodePrefix = (node.namespaceURI === "" ? "" : node.prefix); - if (nodePrefix) { - nodePrefix += ":"; - } - var nodeName = nodePrefix + tagName; - return nodeName === tagName; - }; - func = function(node, tagName){ - var criteria; - if (tagName === "*") { - criteria = null; + function _ajax(options){ + var xhr, args, headers, header, + handlerCalled = false, + handler = function(){ + handlerCalled = true; + if (xhr.response.length > 10000000) { + // Responses beyond a certain size blow up the memory limits in Chrome + var err = Xmla.Exception._newError( + "HTTP_ERROR", + "_ajax", + { + request: options, + status: this.status, + statusText: this.statusText, + xhr: xhr, + detail: "SIZE", + details: "SIZE" + }, + "SIZE" + ) + options.error(err); + xhr.abort(); + throw 'Outsize response - throw it away' + return + } + switch (xhr.readyState){ + case 0: + if (_isFun(options.aborted)) { + options.aborted(xhr); + } + break; + case 4: + //See https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0 + //Preflight request is acceptable if the HTTP status code is in the 2xx range + //Specifically, Windows IIS may return a 204 rather than a 200 code to the OPTIONS request + if (xhr.status >= 200 && xhr.status <= 299) { + options.complete(xhr) + } + else { + var err = Xmla.Exception._newError( + "HTTP_ERROR", + "_ajax", + { + request: options, + status: this.status, + statusText: this.statusText, + xhr: xhr + } + ) + //console.log(err); + //When I have an error in HTTP, this allows better debugging + //So made an extra call instead of _newError inside func call + options.error(err); + } + break; + } + }; + + xhr = _createXhr(); + args = ["POST", options.url, options.async]; + if (options.username && options.password) { + args = args.concat([options.username, options.password]); + } + xhr.open.apply(xhr, args); + + //It is necessary for the XML HTTP Request to send credentials when IIS is in Windows Authentication mode, with Anonymous Authentication turned off and the Access-Control-Allow-Credentials header is set + //See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials + xhr.withCredentials = true; + + //see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute + if (!_isUnd(options.requestTimeout) && (options.async || !(window && window.document))) { + xhr.timeout = options.requestTimeout; + } + xhr.onreadystatechange = handler; + xhr.setRequestHeader("Accept", "text/xml, application/xml, application/soap+xml"); + xhr.setRequestHeader("Content-Type", "text/xml"); + if (headers = options.headers) { + for (header in headers) { + xhr.setRequestHeader(header, headers[header]); } - else { - criteria = checkCriteria; + } + xhr.send(options.data); + if (!options.async && !handlerCalled) { + handler.call(xhr); + } + return xhr; + }; + + function _isUnd(arg){ + return typeof(arg)==="undefined"; + }; + function _isArr(arg){ + return arg && arg.constructor === Array; + }; + function _isNum(arg){ + return typeof(arg)==="number"; + }; + function _isFun(arg){ + return typeof(arg)==="function"; + }; + function _isStr(arg) { + return typeof(arg)==="string"; + }; + function _isObj(arg) { + return arg && typeof(arg)==="object"; + }; + function _xmlEncode(value){ + var value; + switch (typeof(value)) { + case "string": + value = value.replace(/\&/g, "&").replace(//g, ">"); + break; + case "undefined": + value = ""; + break; + case "object": + if (value === null) { + value = ""; } - - var list = []; - _getElements(node, list, criteria); - - return list; - }; - } - return (_getElementsByTagName = func)(node, tagName); -}; - -var _getElementsByTagNameNS = function(node, ns, prefix, tagName){ - var func; - if ("getElementsByTagNameNS" in node) { - func = function(node, ns, prefix, tagName) { - return node.getElementsByTagNameNS(ns, tagName); - }; - } - else - if ("getElementsByTagName" in node) { - func = function(node, ns, prefix, tagName){ - return node.getElementsByTagName((prefix ? prefix + ":" : "") + tagName); - }; + } + return value; + }; + + function _decodeXmlaTagName(tagName) { + return tagName.replace(/_x(\d\d\d\d)_/g, function(match, hex, offset){ + return String.fromCharCode(parseInt(hex, 16)); + }); } - else { - func = function(node, ns, prefix, tagName){ - var list = [], criteria; - if (tagName === "*") { - criteria = function(_node){ - return (_node.nodeType === 1 && _node.namespaceURI === ns); - }; - } - else { - criteria = function(_node){ - return (_node.nodeType === 1 && _node.namespaceURI === ns && _node.nodeName === tagName); - }; - } + //this is here to support (partial) dom interface on top of our own document implementation + //we don't need this in the browser, it's here when running in environments without a native xhr + //where the xhr object does not offer a DOM responseXML object. + function _getElements(parent, list, criteria){ + var childNodes = parent.childNodes; + if (!childNodes) return list; + for (var node, i = 0, n = childNodes.length; i < n; i++){ + node = childNodes[i]; + if (criteria && criteria.call(null, node) === true) list.push(node); _getElements(node, list, criteria); - return list; - }; - } - _getElementsByTagNameNS = func; - return func(node, ns, prefix, tagName); -}; - -var _getAttributeNS = function(element, ns, prefix, attributeName) { - var func; - if ("getAttributeNS" in element) { - func = function(element, ns, prefix, attributeName){ - return element.getAttributeNS(ns, attributeName); - }; - } - else - if ("getAttribute" in element) { - func = function(element, ns, prefix, attributeName){ - return element.getAttribute((prefix ? prefix + ":" : "") + attributeName); - }; - } - else { - func = function(element, namespaceURI, prefix, attributeName){ - var attributes = element.attributes; - if (!attributes) return null; - for (var attr, i = 0, n = attributes.length; i < n; i++) { - attr = attributes[i]; - if (attr.namespaceURI === namespaceURI && attr.nodeName === attributeName) return attr.value; - } - return null; - }; - } - return (_getAttributeNS = func)(element, ns, prefix, attributeName); -}; - -var _getAttribute = function(node, name){ - var func; - if ("getAttribute" in node) { - func = function(node, name){ - return node.getAttribute(name); - }; - } - else { - func = function(node, name) { - var attributes = node.attributes; - if (!attributes) return null; - for (var attr, i = 0, n = attributes.length; i < n; i++) { - attr = attributes[i]; - if (attr.nodeName === name) return attr.value; - } - return null; - }; - } - return (_getAttribute = func)(node, name); -}; - -function _getElementText(el){ - //on first call, we examine the properies of the argument element - //to try and find a native (and presumably optimized) method to grab - //the text value of the element. - //We then overwrite the original _getElementText - //to use the optimized one in any subsequent calls - var func; - if ("textContent" in el) { //ff, chrome - func = function(el){ - return el.textContent; - }; - } - else - if ("nodeTypedValue" in el) { //ie8 - func = function(el){ - return el.nodeTypedValue; - }; - } - else - if ("innerText" in el) { //ie - func = function(el){ - return el.innerText; - }; - } - else - if ("normalize" in el){ - func = function(el) { - el.normalize(); - if (el.firstChild){ - return el.firstChild.data; - } - else { + } + }; + + var _getElementsByTagName = function(node, tagName){ + var func; + if ("getElementsByTagName" in node) { + func = function(node, tagName) { + return node.getElementsByTagName(tagName); + }; + } + else { + var checkCriteria = function(node){ + if (node.nodeType !== 1) { + return false; + } + var nodePrefix = (node.namespaceURI === "" ? "" : node.prefix); + if (nodePrefix) { + nodePrefix += ":"; + } + var nodeName = nodePrefix + tagName; + return nodeName === tagName; + }; + func = function(node, tagName){ + var criteria; + if (tagName === "*") { + criteria = null; + } + else { + criteria = checkCriteria; + } + + var list = []; + _getElements(node, list, criteria); + + return list; + }; + } + return (_getElementsByTagName = func)(node, tagName); + }; + + var _getElementsByTagNameNS = function(node, ns, prefix, tagName){ + var func; + if ("getElementsByTagNameNS" in node) { + func = function(node, ns, prefix, tagName) { + return node.getElementsByTagNameNS(ns, tagName); + }; + } + else + if ("getElementsByTagName" in node) { + func = function(node, ns, prefix, tagName){ + return node.getElementsByTagName((prefix ? prefix + ":" : "") + tagName); + }; + } + else { + func = function(node, ns, prefix, tagName){ + var list = [], criteria; + if (tagName === "*") { + criteria = function(_node){ + return (_node.nodeType === 1 && _node.namespaceURI === ns); + }; + } + else { + criteria = function(_node){ + return (_node.nodeType === 1 && _node.namespaceURI === ns && _node.nodeName === tagName); + }; + } + _getElements(node, list, criteria); + return list; + }; + } + _getElementsByTagNameNS = func; + return func(node, ns, prefix, tagName); + }; + + var _getAttributeNS = function(element, ns, prefix, attributeName) { + var func; + if ("getAttributeNS" in element) { + func = function(element, ns, prefix, attributeName){ + return element.getAttributeNS(ns, attributeName); + }; + } + else + if ("getAttribute" in element) { + func = function(element, ns, prefix, attributeName){ + return element.getAttribute((prefix ? prefix + ":" : "") + attributeName); + }; + } + else { + func = function(element, namespaceURI, prefix, attributeName){ + var attributes = element.attributes; + if (!attributes) return null; + for (var attr, i = 0, n = attributes.length; i < n; i++) { + attr = attributes[i]; + if (attr.namespaceURI === namespaceURI && attr.nodeName === attributeName) return attr.value; + } return null; - } + }; } - } - else { //generic - func = function(el) { - var text = [], childNode, - childNodes = el.childNodes, i, - n = childNodes ? childNodes.length : 0 - ; - for (i = 0; i < n; i++){ - childNode = childNodes[i]; - if (childNode.data !== null) text.push(childNode.data); + return (_getAttributeNS = func)(element, ns, prefix, attributeName); + }; + + var _getAttribute = function(node, name){ + var func; + if ("getAttribute" in node) { + func = function(node, name){ + return node.getAttribute(name); + }; + } + else { + func = function(node, name) { + var attributes = node.attributes; + if (!attributes) return null; + for (var attr, i = 0, n = attributes.length; i < n; i++) { + attr = attributes[i]; + if (attr.nodeName === name) return attr.value; + } + return null; + }; + } + return (_getAttribute = func)(node, name); + }; + + function _getElementText(el){ + //on first call, we examine the properies of the argument element + //to try and find a native (and presumably optimized) method to grab + //the text value of the element. + //We then overwrite the original _getElementText + //to use the optimized one in any subsequent calls + var func; + if ("textContent" in el) { //ff, chrome + func = function(el){ + return el.textContent; + }; + } + else + if ("nodeTypedValue" in el) { //ie8 + func = function(el){ + return el.nodeTypedValue; + }; + } + else + if ("innerText" in el) { //ie + func = function(el){ + return el.innerText; + }; + } + else + if ("normalize" in el){ + func = function(el) { + el.normalize(); + if (el.firstChild){ + return el.firstChild.data; + } + else { + return null; + } } - return text.length ? text.join("") : null; } - } - _getElementText = func; - return func(el); -}; - -function _getXmlaSoapList(container, listType, items, indent){ - if (!indent) indent = ""; - var n, i, entry, property, item, msg = "\n" + indent + "<" + container + ">"; - if (items) { - msg += "\n" + indent + " <" + listType + ">"; - for (property in items){ - if (items.hasOwnProperty(property)) { - item = items[property]; - msg += "\n" + indent + " <" + property + ">"; - if (_isArr(item)){ - n = item.length; - for (i = 0; i < n; i++){ - entry = item[i]; - msg += "" + _xmlEncode(entry) + ""; - } - } else { - msg += _xmlEncode(item); + else { //generic + func = function(el) { + var text = [], childNode, + childNodes = el.childNodes, i, + n = childNodes ? childNodes.length : 0 + ; + for (i = 0; i < n; i++){ + childNode = childNodes[i]; + if (childNode.data !== null) text.push(childNode.data); } - msg += ""; + return text.length ? text.join("") : null; } } - msg += "\n" + indent + " "; - } - msg += "\n" + indent + ""; - return msg; -}; - -var _xmlRequestType = "RequestType"; - -function _applyProps(object, properties, overwrite){ - if (properties && (!object)) { - object = {}; - } - var property; - for (property in properties){ - if (properties.hasOwnProperty(property)){ - if (overwrite || _isUnd(object[property])) { - object[property] = properties[property]; + _getElementText = func; + return func(el); + }; + + function _getXmlaSoapList(container, listType, items, indent){ + if (!indent) indent = ""; + var n, i, entry, property, item, msg = "\n" + indent + "<" + container + ">"; + if (items) { + msg += "\n" + indent + " <" + listType + ">"; + for (property in items){ + if (items.hasOwnProperty(property)) { + item = items[property]; + msg += "\n" + indent + " <" + property + ">"; + if (_isArr(item)){ + n = item.length; + for (i = 0; i < n; i++){ + entry = item[i]; + msg += "" + _xmlEncode(entry) + ""; + } + } else { + msg += _xmlEncode(item); + } + msg += ""; + } } + msg += "\n" + indent + " "; } - } - return object; -}; - -function _xjs(xml) { - // 1234 5 6 789 10 11 12 13 14 15 - var re = /<(((([\w\-\.]+):)?([\w\-\.]+))([^>]+)?|\/((([\w\-\.]+):)?([\w\-\.]+))|\?(\w+)([^\?]+)?\?|(!--([^\-]|-[^\-])*--))>|([^<>]+)/ig, - match, name, prefix, atts, ePrefix, eName, piTarget, text, - ns = {"": ""}, newNs, nsUri, doc, parentNode, namespaces = [], nextParent, node = null - ; - doc = parentNode = { - nodeType: 9, - childNodes: [] - }; - - function Ns(){ - namespaces.push(ns); - var _ns = new (function(){}); - _ns.constructor.prototype = ns; - ns = new _ns.constructor(); - node.namespaces = ns; - newNs = true; - } - function popNs() { - ns = namespaces.pop(); - } - function unescapeEntities(text) { - return text.replace(/&((\w+)|#(x?)([0-9a-fA-F]+));/g, function(match, g1, g2, g3, g4, idx, str){ - if (g2) { - var v = ({ - lt: "<", - gt: ">", - amp: "&", - apos: "'", - quot: "\"" - })[g2]; - if (v) { - return v; + msg += "\n" + indent + ""; + return msg; + }; + + var _xmlRequestType = "RequestType"; + + function _applyProps(object, properties, overwrite){ + if (properties && (!object)) { + object = {}; } - else { - throw "Illegal named entity: " + g2; + var property; + for (property in properties){ + if (properties.hasOwnProperty(property)){ + if (overwrite || _isUnd(object[property])) { + object[property] = properties[property]; + } + } } + return object; + }; + + function _xjs(xml) { + // 1234 5 6 789 10 11 12 13 14 15 + var re = /<(((([\w\-\.]+):)?([\w\-\.]+))([^>]+)?|\/((([\w\-\.]+):)?([\w\-\.]+))|\?(\w+)([^\?]+)?\?|(!--([^\-]|-[^\-])*--))>|([^<>]+)/ig, + match, name, prefix, atts, ePrefix, eName, piTarget, text, + ns = {"": ""}, newNs, nsUri, doc, parentNode, namespaces = [], nextParent, node = null + ; + doc = parentNode = { + nodeType: 9, + childNodes: [] + }; + + function Ns(){ + namespaces.push(ns); + var _ns = new (function(){}); + _ns.constructor.prototype = ns; + ns = new _ns.constructor(); + node.namespaces = ns; + newNs = true; } - else { - return String.fromCharCode(parseInt(g4, g3 ? 16: 10)); + function popNs() { + ns = namespaces.pop(); } - }); - } - while (match = re.exec(xml)) { - node = null; - if (name = match[5]) { - newNs = false; - node = { - offset: match.index, - parentNode: parentNode, - nodeType: 1, - nodeName: name - }; - nextParent = node; - if (atts = match[6]) { - if (atts.length && atts.substr(atts.length - 1, 1) === "\/") { - nextParent = node.parentNode; - if (ns === node.namespaces) popNs(); - atts = atts.substr(0, atts.length - 1); - } - var attMatch, att; - // 123 4 5 6 7 - var attRe = /((([\w\-]+):)?([\w\-]+))\s*=\s*('([^']*)'|"([^"]*)")/g; - while(attMatch = attRe.exec(atts)) { - var pfx = attMatch[3] || "", - value = attMatch[attMatch[6] ? 6 : 7] - ; - if (attMatch[1].indexOf("xmlns")) { - if (!node.attributes) node.attributes = []; - att = { - nodeType: 2, - prefix: pfx, - nodeName: attMatch[4], - value: unescapeEntities(value) - }; - nsUri = (pfx === "") ? "" : ns[pfx]; - if (_isUnd(nsUri)) { - throw "Unrecognized namespace with prefix \"" + prefix + "\""; - } - att.namespaceURI = nsUri; - node.attributes.push(att); + function unescapeEntities(text) { + return text.replace(/&((\w+)|#(x?)([0-9a-fA-F]+));/g, function(match, g1, g2, g3, g4, idx, str){ + if (g2) { + var v = ({ + lt: "<", + gt: ">", + amp: "&", + apos: "'", + quot: "\"" + })[g2]; + if (v) { + return v; + } + else { + throw "Illegal named entity: " + g2; + } + } + else { + return String.fromCharCode(parseInt(g4, g3 ? 16: 10)); + } + }); + } + while (match = re.exec(xml)) { + node = null; + if (name = match[5]) { + newNs = false; + node = { + offset: match.index, + parentNode: parentNode, + nodeType: 1, + nodeName: name + }; + nextParent = node; + if (atts = match[6]) { + if (atts.length && atts.substr(atts.length - 1, 1) === "\/") { + nextParent = node.parentNode; + if (ns === node.namespaces) popNs(); + atts = atts.substr(0, atts.length - 1); } - else { - if (!newNs) Ns(); - ns[attMatch[3] ? attMatch[4] : ""] = value; + var attMatch, att; + // 123 4 5 6 7 + var attRe = /((([\w\-]+):)?([\w\-]+))\s*=\s*('([^']*)'|"([^"]*)")/g; + while(attMatch = attRe.exec(atts)) { + var pfx = attMatch[3] || "", + value = attMatch[attMatch[6] ? 6 : 7] + ; + if (attMatch[1].indexOf("xmlns")) { + if (!node.attributes) node.attributes = []; + att = { + nodeType: 2, + prefix: pfx, + nodeName: attMatch[4], + value: unescapeEntities(value) + }; + nsUri = (pfx === "") ? "" : ns[pfx]; + if (_isUnd(nsUri)) { + throw "Unrecognized namespace with prefix \"" + prefix + "\""; + } + att.namespaceURI = nsUri; + node.attributes.push(att); + } + else { + if (!newNs) Ns(); + ns[attMatch[3] ? attMatch[4] : ""] = value; + } } + attRe.lastIndex = 0; + } + prefix = match[4] || ""; + node.prefix = prefix; + nsUri = ns[prefix]; + if (_isUnd(nsUri)) { + throw "Unrecognized namespace with prefix \"" + prefix + "\""; + } + node.namespaceURI = nsUri; + } + else + if (eName = match[10]) { + ePrefix = match[9] || ""; + if (parentNode.nodeName === eName && parentNode.prefix === ePrefix) { + nextParent = parentNode.parentNode; + if (ns === parentNode.namespaces) popNs(); } - attRe.lastIndex = 0; + else throw "Unclosed tag " + ePrefix + ":" + eName; } - prefix = match[4] || ""; - node.prefix = prefix; - nsUri = ns[prefix]; - if (_isUnd(nsUri)) { - throw "Unrecognized namespace with prefix \"" + prefix + "\""; + else + if (piTarget = match[11]) { + node = { + offset: match.index, + parentNode: parentNode, + target: piTarget, + data: match[12], + nodeType: 7 + }; } - node.namespaceURI = nsUri; - } - else - if (eName = match[10]) { - ePrefix = match[9] || ""; - if (parentNode.nodeName === eName && parentNode.prefix === ePrefix) { - nextParent = parentNode.parentNode; - if (ns === parentNode.namespaces) popNs(); + else + if (match[13]) { + node = { + offset: match.index, + parentNode: parentNode, + nodeType: 8, + data: match[14] + }; } - else throw "Unclosed tag " + ePrefix + ":" + eName; - } - else - if (piTarget = match[11]) { - node = { - offset: match.index, - parentNode: parentNode, - target: piTarget, - data: match[12], - nodeType: 7 - }; - } - else - if (match[13]) { - node = { - offset: match.index, - parentNode: parentNode, - nodeType: 8, - data: match[14] - }; - } - else - if ((text = match[15]) && (!/^\s+$/.test(text))) { - node = { - offset: match.index, - parentNode: parentNode, - nodeType: 3, - data: unescapeEntities(text) - }; - } - if (node) { - if (!parentNode.childNodes) parentNode.childNodes = []; - parentNode.childNodes.push(node); + else + if ((text = match[15]) && (!/^\s+$/.test(text))) { + node = { + offset: match.index, + parentNode: parentNode, + nodeType: 3, + data: unescapeEntities(text) + }; + } + if (node) { + if (!parentNode.childNodes) parentNode.childNodes = []; + parentNode.childNodes.push(node); + } + if (nextParent) parentNode = nextParent; } - if (nextParent) parentNode = nextParent; - } - return doc; -}; - -/** -* -* The Xmla class provides a javascript API to communicate XML for Analysis (XML/A) over HTTP. -* XML/A is an industry standard protocol that allows webclients to work with OLAP servers. -* To fully understand the scope and purpose of this utility, it is highly recommended -* to read the XML/A specification -* (MS Word format. For other formats, -* see: http://code.google.com/p/xmla4js/source/browse/#svn/trunk/doc/xmla1.1 specification). -* -* The optional options parameter sets standard options for this Xmla instnace. -* If ommitted, a copy of the defaultOptions will be used. -* -* @class Xmla -* @constructor -* @param options Object standard options -*/ -Xmla = function(options){ - - this.listeners = {}; - this.listeners[Xmla.EVENT_REQUEST] = []; - this.listeners[Xmla.EVENT_SUCCESS] = []; - this.listeners[Xmla.EVENT_ERROR] = []; - - this.listeners[Xmla.EVENT_DISCOVER] = []; - this.listeners[Xmla.EVENT_DISCOVER_SUCCESS] = []; - this.listeners[Xmla.EVENT_DISCOVER_ERROR] = []; - - this.listeners[Xmla.EVENT_EXECUTE] = []; - this.listeners[Xmla.EVENT_EXECUTE_SUCCESS] = []; - this.listeners[Xmla.EVENT_EXECUTE_ERROR] = []; - - this.options = _applyProps( - _applyProps({}, Xmla.defaultOptions, true), - options, true - ); - var listeners = this.options.listeners; - if (listeners) this.addListener(listeners); - return this; -}; - -/** -* These are the default options used for new Xmla instances in case no custom properties are set. -* It sets the following properties: -* -* -* @property defaultOptions -* @static -* @type object -**/ -Xmla.defaultOptions = { - requestTimeout: 30000, //by default, we bail out after 30 seconds - async: false, //by default, we do a synchronous request - addFieldGetters: true, //true to augment rowsets with a method to fetch a specific field. - //forceResponseXMLEmulation: true //true to use our own XML parser instead of XHR's native responseXML. Useful for testing. - forceResponseXMLEmulation: false //true to use our own XML parser instead of XHR's native responseXML. Useful for testing. -}; - -/** -* Can be used as value for the method option in the options object passed to the -* request() method to invoke the XML/A Discover method on the server. -* Instead of explicitly setting the method yourself, consider using the discover() method. -* The discover() method automatically sets the method option to METHOD_DISCOVER. -* @property METHOD_DISCOVER -* @static -* @final -* @type string -* @default Discover -*/ -Xmla.METHOD_DISCOVER = "Discover"; -/** -* Can be used as value for the method option property in the options objecct passed to the -* request() method to invoke the XML/A Execute method on the server. -* Instead of explicitly setting the method yourself, consider using the execute() method. -* The execute() method automatically sets the method option to METHOD_EXECUTE. -* @property METHOD_EXECUTE -* @static -* @final -* @type string -* @default Discover -*/ -Xmla.METHOD_EXECUTE = "Execute"; - -var _xmlaDISCOVER = "DISCOVER_"; -var _xmlaMDSCHEMA = "MDSCHEMA_"; -var _xmlaDBSCHEMA = "DBSCHEMA_"; - -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DISCOVER_DATASOURCES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this constant as requestType yourself, consider calling the discoverDataSources() method. -* The discoverDataSources() method passes DISCOVER_DATASOURCES automatically as requestType for Discover requests. -* -* @property DISCOVER_DATASOURCES -* @static -* @final -* @type string -* @default DISCOVER_DATASOURCES -*/ -Xmla.DISCOVER_DATASOURCES = _xmlaDISCOVER + "DATASOURCES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DISCOVER_PROPERTIES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverProperties() method. -* The discoverProperties() method passes DISCOVER_PROPERTIES automatically as requestType for Discover requests. -* -* @property DISCOVER_PROPERTIES -* @static -* @final -* @type string -* @default DISCOVER_PROPERTIES -*/ -Xmla.DISCOVER_PROPERTIES = _xmlaDISCOVER + "PROPERTIES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DISCOVER_SCHEMA_ROWSETS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverSchemaRowsets() method. -* The discoverProperties() method passes DISCOVER_PROPERTIES automatically as requestType for Discover requests. -* -* @property DISCOVER_SCHEMA_ROWSETS -* @static -* @final -* @type string -* @default DISCOVER_SCHEMA_ROWSETS -*/ -Xmla.DISCOVER_SCHEMA_ROWSETS = _xmlaDISCOVER + "SCHEMA_ROWSETS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DISCOVER_ENUMERATORS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverEnumerators() method. -* The discoverSchemaRowsets() method issues a request to invoke the Discover method using DISCOVER_SCHEMA_ROWSETS as requestType. -* -* @property DISCOVER_ENUMERATORS -* @static -* @final -* @type string -* @default DISCOVER_ENUMERATORS -*/ -Xmla.DISCOVER_ENUMERATORS = _xmlaDISCOVER + "ENUMERATORS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DISCOVER_KEYWORDS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverKeywords() method. -* The discoverKeywords() method issues a request to invoke the Discover method using DISCOVER_KEYWORDS as requestType. -* -* @property DISCOVER_KEYWORDS -* @static -* @final -* @type string -* @default DISCOVER_KEYWORDS -*/ -Xmla.DISCOVER_KEYWORDS = _xmlaDISCOVER + "KEYWORDS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DISCOVER_LITERALS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverLiterals() method. -* The discoverLiterals() method issues a request to invoke the Discover method using DISCOVER_LITERALS as requestType. -* -* @property DISCOVER_LITERALS -* @static -* @final -* @type string -* @default DISCOVER_LITERALS -*/ -Xmla.DISCOVER_LITERALS = _xmlaDISCOVER + "LITERALS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_CATALOGS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverDBCatalogs() method. -* The discoverDBCatalogs() method issues a request to invoke the Discover method using DBSCHEMA_CATALOGS as requestType. -* -* @property DBSCHEMA_CATALOGS -* @static -* @final -* @type string -* @default DBSCHEMA_CATALOGS -*/ -Xmla.DBSCHEMA_CATALOGS = _xmlaDBSCHEMA + "CATALOGS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_COLUMNS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverDBColumns() method. -* The discoverDBColumns() method issues a request to invoke the Discover method using DBSCHEMA_COLUMNS as requestType. -* -* @property DBSCHEMA_COLUMNS -* @static -* @final -* @type string -* @default DBSCHEMA_COLUMNS -*/ -Xmla.DBSCHEMA_COLUMNS = _xmlaDBSCHEMA + "COLUMNS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_PROVIDER_TYPES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverDBProviderTypes() method. -* The discoverDBProviderTypes() method issues a request to invoke the Discover method using DBSCHEMA_PROVIDER_TYPES as requestType. -* -* @property DBSCHEMA_PROVIDER_TYPES -* @static -* @final -* @type string -* @default DBSCHEMA_PROVIDER_TYPES -*/ -Xmla.DBSCHEMA_PROVIDER_TYPES = _xmlaDBSCHEMA + "PROVIDER_TYPES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_SCHEMATA schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverDBSchemata() method. -* The discoverDBColumns() method issues a request to invoke the Discover method using DBSCHEMA_SCHEMATA as requestType. -* -* @property DBSCHEMA_SCHEMATA -* @static -* @final -* @type string -* @default DBSCHEMA_SCHEMATA -*/ -Xmla.DBSCHEMA_SCHEMATA = _xmlaDBSCHEMA + "SCHEMATA"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_TABLES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the discoverDBTables() method. -* The discoverDBColumns() method issues a request to invoke the Discover method using DBSCHEMA_TABLES as requestType. -* -* @property DBSCHEMA_TABLES -* @static -* @final -* @type string -* @default DBSCHEMA_TABLES -*/ -Xmla.DBSCHEMA_TABLES = _xmlaDBSCHEMA + "TABLES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_TABLES_INFO schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverDBTablesInfo() method. -* The discoverDBTablesInfo() method issues a request to invoke the Discover method using DBSCHEMA_TABLES_INFO as requestType. -* -* @property DBSCHEMA_TABLES_INFO -* @static -* @final -* @type string -* @default DBSCHEMA_TABLES_INFO -*/ -Xmla.DBSCHEMA_TABLES_INFO = _xmlaDBSCHEMA + "TABLES_INFO"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the MDSCHEMA_ACTIONS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDActions() method. -* The discoverMDActions() method issues a request to invoke the Discover method using MDSCHEMA_ACTIONS as requestType. -* -* @property MDSCHEMA_ACTIONS -* @static -* @final -* @type string -* @default MDSCHEMA_ACTIONS -*/ -Xmla.MDSCHEMA_ACTIONS = _xmlaMDSCHEMA + "ACTIONS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_CUBES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDCubes() method. -* The discoverMDCubes() method issues a request to invoke the Discover method using -* MDSCHEMA_CUBES as requestType. -* -* @property MDSCHEMA_CUBES -* @static -* @final -* @type string -* @default MDSCHEMA_CUBES -*/ -Xmla.MDSCHEMA_CUBES = _xmlaMDSCHEMA + "CUBES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_DIMENSIONS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDDimensions() method. -* The discoverMDDimensions() method issues a request to invoke the Discover method using -* MDSCHEMA_DIMENSIONS as requestType. -* -* @property MDSCHEMA_DIMENSIONS -* @static -* @final -* @type string -* @default MDSCHEMA_DIMENSIONS -*/ -Xmla.MDSCHEMA_DIMENSIONS = _xmlaMDSCHEMA + "DIMENSIONS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_FUNCTIONS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDFunctions() method. -* The discoverMDFunctions() method issues a request to invoke the Discover method using -* MDSCHEMA_FUNCTIONS as requestType. -* -* @property MDSCHEMA_FUNCTIONS -* @static -* @final -* @type string -* @default MDSCHEMA_FUNCTIONS -*/ -Xmla.MDSCHEMA_FUNCTIONS = _xmlaMDSCHEMA + "FUNCTIONS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_HIERARCHIES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDHierarchies() method. -* The discoverMDHierarchies() method issues a request to invoke the Discover method using -* MDSCHEMA_HIERARCHIES as requestType. -* -* @property MDSCHEMA_HIERARCHIES -* @static -* @final -* @type string -* @default MDSCHEMA_HIERARCHIES -*/ -Xmla.MDSCHEMA_HIERARCHIES = _xmlaMDSCHEMA + "HIERARCHIES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_LEVELS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDLevels() method. -* The discoverMDLevels() method issues a request to invoke the Discover method using -* MDSCHEMA_LEVELS as requestType. -* -* @property MDSCHEMA_LEVELS -* @static -* @final -* @type string -* @default MDSCHEMA_LEVELS -*/ -Xmla.MDSCHEMA_LEVELS = _xmlaMDSCHEMA + "LEVELS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_MEASURES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDMeasures() method. -* The discoverMDMeasures() method issues a request to invoke the Discover method using -* MDSCHEMA_MEASURES as requestType. -* -* @property MDSCHEMA_MEASURES -* @static -* @final -* @type string -* @default MDSCHEMA_MEASURES -*/ -Xmla.MDSCHEMA_MEASURES = _xmlaMDSCHEMA + "MEASURES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_MEMBERS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDMembers() method. -* The discoverMDMembers() method issues a request to invoke the Discover method using -* MDSCHEMA_MEMBERS as requestType. -* -* @property MDSCHEMA_MEMBERS -* @static -* @final -* @type string -* @default MDSCHEMA_MEMBERS -*/ -Xmla.MDSCHEMA_MEMBERS = _xmlaMDSCHEMA + "MEMBERS"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_PROPERTIES schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDProperties() method. -* The discoverMDProperties() method issues a request to invoke the Discover method using -* MDSCHEMA_PROPERTIES as requestType. -* -* @property MDSCHEMA_PROPERTIES -* @static -* @final -* @type string -* @default MDSCHEMA_PROPERTIES -*/ -Xmla.MDSCHEMA_PROPERTIES = _xmlaMDSCHEMA + "PROPERTIES"; -/** -* Can be used as value for the requestType option in the options object passed to the to -* request() method to invoke the XML/A Discover method on the server to return the -* MDSCHEMA_SETS schema rowset. -* The requestType option applies only to Discover requests. -* Instead of passing this requestType yourself, consider calling the -* discoverMDSets() method. -* The discoverMDSets() method issues a request to invoke the Discover method using -* MDSCHEMA_SETS as requestType. -* -* @property MDSCHEMA_SETS -* @static -* @final -* @type string -* @default MDSCHEMA_SETS -*/ -Xmla.MDSCHEMA_SETS = _xmlaMDSCHEMA + "SETS"; -/** -* Indicates the request event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The request event is the first event that is fired before submitting a request -* (see: request()) -* to the server, and before firing the method-specific request events -* (see EVENT_EXECUTE -* and EVENT_DISCOVER). -* The request event itself is not method-specific, and fires for Execute as well as Discover requests. -* The EVENT_REQUEST event is cancelable: -* the handler function specified in the listener object passed to addListener should return a boolen, indicating -* whether the respective operation should be canceled. -* -* @property EVENT_REQUEST -* @static -* @final -* @type string -* @default request -*/ -Xmla.EVENT_REQUEST = "request"; -/** -* Indicates the success event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The success event is the last event that is fired after receiving and processing a normal response -* (that is, a response that does not contain an XML/A SoapFault), -* after firing the method-specific success events -* (see EVENT_EXECUTE_SUCCESS -* and EVENT_DISCOVER_SUCCESS). -* The success event is not method-specific, and fires for Execute as well as Discover responses. -* This is event is not cancelable. -* -* @property EVENT_SUCCESS -* @static -* @final -* @type string -* @default success -*/ -Xmla.EVENT_SUCCESS = "success"; -/** -* Indicates the error event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The error is fired when an error occurs while sending a request or receiving a response. -* The error event is not method-specific, and fires for errors encountered during both Execute as well as Discover method invocations. -* This is event is not cancelable. -* -* @property EVENT_ERROR -* @static -* @final -* @type string -* @default error -*/ -Xmla.EVENT_ERROR = "error"; - -/** -* Indicates the execute event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The execute event is method-specific, and is fired before submitting an Execute request -* (see: execute()) -* to the server, but after firing the request event -* (see: EVENT_REQUEST). -* The EVENT_EXECUTE event is cancelable: -* the handler function specified in the listener object passed to addListener should return a boolen, indicating -* whether the respective operation should be canceled. -* -* @property EVENT_EXECUTE -* @static -* @final -* @type string -* @default execute -*/ -Xmla.EVENT_EXECUTE = "execute"; -/** -* Indicates the executesuccess event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The executesuccess event is method-specific and fired only after receiving and processing a normal response -* (that is, a response that does not contain a SoapFault) -* to an incovation of the XML/A Execute method -* (see: execute()). -* This is event is not cancelable. -* -* @property EVENT_EXECUTE_SUCCESS -* @static -* @final -* @type string -* @default executesuccess -*/ -Xmla.EVENT_EXECUTE_SUCCESS = "executesuccess"; -/** -* Indicates the executeerror event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The executeerror event is method-specific and fired when an error occurs while sending an Execute request, or receiving a response to an Execute method. -* (see: execute()). -* This is event is not cancelable. -* -* @property EVENT_EXECUTE_ERROR -* @static -* @final -* @type string -* @default executeerror -*/ -Xmla.EVENT_EXECUTE_ERROR = "executeerror"; - -/** -* Indicates the discover event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The discover event is method-specific, and is fired before submitting a Discover request -* (see: discover()) -* to the server, but after firing the request event -* (see: EVENT_DISCOVER). -* The EVENT_DISCOVER event is cancelable: -* the handler function specified in the listener object passed to addListener should return a boolen, indicating -* whether the respective operation should be canceled. -* -* @property EVENT_DISCOVER -* @static -* @final -* @type string -* @default discover -*/ -Xmla.EVENT_DISCOVER = "discover"; -/** -* Indicates the discoversuccess event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The discoversuccess event is method-specific and fired only after receiving and processing a normal response -* (that is, a response that does not contain a SoapFault) -* to an incovation of the XML/A Discover method -* (see: discover()). -* This is event is not cancelable. -* -* @property EVENT_DISCOVER_SUCCESS -* @static -* @final -* @type string -* @default discoversuccess -*/ -Xmla.EVENT_DISCOVER_SUCCESS = "discoversuccess"; -/** -* Indicates the discovererror event. -* This constant can be used as en entry in the events array argument for the addListener() method. -* The discovererror is method-specific and fired when an error occurs while sending an Discover request, -* or receiving a response to an Discover method. -* (see: discover()). -* This is event is not cancelable. -* -* @property EVENT_DISCOVER_ERROR -* @static -* @final -* @type string -* @default discovererror -*/ -Xmla.EVENT_DISCOVER_ERROR = "discovererror"; - -/** -* Unifies all general events, that is, all events that are not method-specific. -* This constant can be used as events array argument for the addListener() method, -* or you can use array concatenation to combine it with other arrays of EVENT_XXX constants. -* This constant is especially intended for asyncronous handling of Schema rowset data. -* -* @property EVENT_GENERAL -* @static -* @final -* @type string[] -* @default [EVENT_REQUEST,EVENT_SUCCESS,EVENT_ERROR] -*/ -Xmla.EVENT_GENERAL = [ - Xmla.EVENT_REQUEST, - Xmla.EVENT_SUCCESS, - Xmla.EVENT_ERROR -]; - -/** -* Unifies all events specific for the Discover method. -* This constant can be used as events array argument for the addListener() method, -* or you can use array concatenation to combine it with other arrays of EVENT_XXX constants. -* -* @property EVENT_DISCOVER_ALL -* @static -* @final -* @type string[] -* @default [EVENT_DISCOVER,EVENT_DISCOVER_SUCCESS,EVENT_DISCOVER_ERROR] -*/ -Xmla.EVENT_DISCOVER_ALL = [ - Xmla.EVENT_DISCOVER, - Xmla.EVENT_DISCOVER_SUCCESS, - Xmla.EVENT_DISCOVER_ERROR -]; - -/** -* Unifies all events specific for the Execute method. -* This constant can be used as events array argument for the addListener() method, -* or you can use array concatenation to combine it with other arrays of EVENT_XXX constants. -* -* @property EVENT_EXECUTE_ALL -* @static -* @final -* @type string[] -* @default [EVENT_EXECUTE,EVENT_EXECUTE_SUCCESS,EVENT_EXECUTE_ERROR] -*/ -Xmla.EVENT_EXECUTE_ALL = [ - Xmla.EVENT_EXECUTE, - Xmla.EVENT_EXECUTE_SUCCESS, - Xmla.EVENT_EXECUTE_ERROR -]; - -/** -* Unifies all method-specific and non method-specific events. -* This constant can be used as events array argument for the addListener() method. -* -* @property EVENT_ALL -* @static -* @final -* @type string[] -* @default [].concat(Xmla.EVENT_GENERAL, Xmla.EVENT_DISCOVER_ALL, Xmla.EVENT_EXECUTE_ALL) -*/ -Xmla.EVENT_ALL = [].concat( - Xmla.EVENT_GENERAL, - Xmla.EVENT_DISCOVER_ALL, - Xmla.EVENT_EXECUTE_ALL -); - -/** -* Can be used as key in the properties member of the options object -* passed to the request() method -* to specify the XML/A DataSourceInfo property. -* The XML/A DataSourceInfo, together with the XML/A service URL are required to -* connect to a particular OLAP datasource. -* Valid values for the DataSourceInfo as well as the corresponding URL should be obtained -* by querying the DataSourceInfo and URL columns of the DISCOVER_DATASOURCES -* rowset respectively (see discoverDataSources()). -* -* @property PROP_DATASOURCEINFO -* @static -* @final -* @type string -* @default DataSourceInfo -*/ -Xmla.PROP_DATASOURCEINFO = "DataSourceInfo"; -/** -* Can be used as key in the properties member of the options object -* passed to the execute() method -* to specify the XML/A Catalog property. -* The XML/A Catalog spefifies where to look for cubes that are referenced in th MDX statment. -* Valid values for the Catalog should be obtained -* by querying the CATALOG_NAME of the DBSCHEMA_CATALOGS -* rowset (see discoverDBCatalogs()). -* -* @property PROP_Catalog -* @static -* @final -* @type string -* @default Catalog -*/ -Xmla.PROP_CATALOG = "Catalog"; -Xmla.PROP_CUBE = "Cube"; - -/** -* Can be used as key in the properties member of the options object -* passed to the execute() method -* to specify the XML/A Format property. -* This property controls the structure of the resultset. -* -* @property PROP_FORMAT -* @static -* @final -* @type string -* @default Format -*/ -Xmla.PROP_FORMAT = "Format"; -/** -* Can be used as value for the -* execute() method. -* When used, this specifies that the multidimensional resultset should be returned in a tabular format, -* causeing the multidimensional resultset to be represented with an instance of the -* Xmla.Rowset class. -* -* @property PROP_FORMAT_TABULAR -* @static -* @final -* @type string -* @default Tabular -*/ -Xmla.PROP_FORMAT_TABULAR = "Tabular"; -/** -* Can be used as value for the -* execute() method. -* When used, this specifies that the multidimensional resultset should be returned in a multidimensional format. -* Currently, Xmla4js does not provide a class to represent the resultset in this format. -* However, you can access the results as xml through the -* responseText and -* responseXML properties. -* -* @property PROP_FORMAT_MULTIDIMENSIONAL -* @static -* @final -* @type string -* @default Multidimensional -*/ -Xmla.PROP_FORMAT_MULTIDIMENSIONAL = "Multidimensional"; - -/** -* Can be used as key in the properties member of the options object -* passed to the execute() method -* to specify the XML/A AxisFormat property. -* The XML/A AxisFormat property specifies how the client wants to receive the multi-dimensional resultset of a MDX query. -* Valid values for the AxisFormat property are available as the static final properties -* PROP_AXISFORMAT_TUPLE, -* PROP_AXISFORMAT_CLUSTER, -* PROP_AXISFORMAT_CUSTOM. -* -* @property PROP_AXISFORMAT -* @static -* @final -* @type string -* @default AxisFormat -*/ -Xmla.PROP_AXISFORMAT = "AxisFormat"; -/** -* Can be used as value for the AxisFormat XML/A property -* (see: PROP_AXISFORMAT) -* in invocations of the Execute method -* (see: execute()). -* -* @property PROP_AXISFORMAT_TUPLE -* @static -* @final -* @type string -* @default TupleFormat -*/ -Xmla.PROP_AXISFORMAT_TUPLE = "TupleFormat"; -/** -* Can be used as value for the AxisFormat XML/A property -* (see: PROP_AXISFORMAT) -* in invocations of the Execute method -* (see: execute()). -* -* @property PROP_AXISFORMAT_CLUSTER -* @static -* @final -* @type string -* @default ClusterFormat -*/ -Xmla.PROP_AXISFORMAT_CLUSTER = "ClusterFormat"; -/** -* Can be used as value for the AxisFormat XML/A property -* (see: PROP_AXISFORMAT) -* in invocations of the Execute method -* (see: execute()). -* -* @property PROP_AXISFORMAT_CUSTOM -* @static -* @final -* @type string -* @default CustomFormat -*/ -Xmla.PROP_AXISFORMAT_CUSTOM = "CustomFormat"; - -/** -* Can be used as key in the properties member of the options object -* passed to the request() method -* to specify the XML/A Content property. -* The XML/A Content property specifies whether to return data and/or XML Schema metadata by the Discover and Execute invocations. -* Valid values for the Content property are available as the static final properties -* PROP_CONTENT_DATA, -* PROP_CONTENT_NONE, -* PROP_CONTENT_SCHEMA, -* PROP_CONTENT_SCHEMADATA. -* -* Note: This key is primarily intended for clients that use the low-level request() method. -* You should not set this property when calling the discover() method, -* the execute() method, -* or any of the discoverXXX() methods. -* -* @property PROP_CONTENT -* @static -* @final -* @type string -* @default Content -*/ -Xmla.PROP_CONTENT = "Content"; -/** -* Can be used as value for the XML/A Content property -* (see: PROP_CONTENT). -* This value specifies that the response should contain only data, but no XML Schema metadata. -* -* As the Xmla class relies on the XML Schema metadata to construct Rowset and Resultset instances, -* this option is primarily useful if you know how to process the XML response directly. -* -* @property PROP_CONTENT_DATA -* @static -* @final -* @type string -* @default Data -*/ -Xmla.PROP_CONTENT_DATA = "Data"; -/** -* Can be used as value for the XML/A Content property -* (see: PROP_CONTENT). -* This value specifies that the response should contain neither data nor XML Schema metadata. -* This is useful to check the validity of the request. -* -* @property PROP_CONTENT_NONE -* @static -* @final -* @type string -* @default None -*/ -Xmla.PROP_CONTENT_NONE = "None"; -/** -* Can be used as value for the XML/A Content property -* (see: PROP_CONTENT). -* This value specifies that the response should only return XML Schema metadata, but no data. -* -* @property PROP_CONTENT_SCHEMA -* @static -* @final -* @type string -* @default Schema -*/ -Xmla.PROP_CONTENT_SCHEMA = "Schema"; -/** -* Can be used as value for the XML/A Content property -* (see: PROP_CONTENT). -* This value specifies that the response should return both data as well as XML Schema metadata. -* -* @property PROP_CONTENT_SCHEMADATA -* @static -* @final -* @type string -* @default SchemaData -*/ -Xmla.PROP_CONTENT_SCHEMADATA = "SchemaData"; - -Xmla.prototype = { -/** -* This object stores listeners. -* Each key is a listener type (see the static final EVENT_XXX constants), -* each value is an array of listener objects that are subscribed to that particular event. -* -* @property listeners -* @protected -* @type Object -* @default
-{
-      "request": []
- ,   "succss": []
- ,   "error": []
- ,   "discover": []
- ,   "discoversuccss": []
- ,   "discovererror": []
- ,   "execute": []
- ,   "executesuccss": []
- ,   "executeerror": []
-}
-*/ - listeners: null, -/** -* The soap message sent in the last request to the server. -* -* @property soapMessage -* @type {string} -* @default null -*/ - soapMessage: null, -/** -* This property is set to null right before sending an XML/A request. -* When a successfull response is received, it is processed and the response object is assigned to this property. -* The response object is either a -* Rowset (after a successful invocation of XML/A Discover method, see: discover()) or a -* Resultset (after a successful invocation of the XML/A Execute method, see: execute()) -* instance. -* -* If you are interested in processing the raw response XML, see -* responseXML and -* responseText. -* -* Note that it is not safe to read this property immediately after doing an asynchronous request. -* For asynchronous requests, you can read this property by the time the XXX_SUCCESS event handlers are notified (until it is set to null again by a subsequent request). -* -* @property response -* @type Xmla.Rowset|Xmla.Dataset -* @default null -*/ - response: null, -/** -* This property is set to null right before sending an XML/A request. -* When a successfull response is received, the XML response is stored to this property as plain text. -* -* If you are interested in processing a DOM document rather than the raw XML text, see the -* responseXML property. -* -* If you are interested in traversing the dataset returned in the XML/A response, see the -* response property. -* -* Note that it is not safe to read this property immediately after doing an asynchronous request. -* For asynchronous requests, you can read this property by the time the XXX_SUCCESS event handlers are notified (until it is set to null again by a subsequent request). -* -* @property responseText -* @type {string} -* @default null -*/ - responseText: null, -/** -* This property is set to null right before sending an XML/A request. -* When a successfull response is received, the XML response is stored to this property as a DOM Document. -* -* If you are interested in processing the raw XML text rather than a DOM document, see the -* responseText property. -* -* If you are interested in traversing the dataset returned in the XML/A response, see the -* response property. -* -* Note that it is not safe to read this property immediately after doing an asynchronous request. -* For asynchronous requests, you can read this property by the time the XXX_SUCCESS event handlers are notified (until it is set to null again by a subsequent request). -* -* @deprecated -* @property responseXML -* @type {DOMDocument} -* @default null -* @see getRep -*/ - responseXML: null, -/** -* @method getResponseXML -* @return {DOMDocument} -*/ - getResponseXML: function(){ - if (this.options.forceResponseXMLEmulation !== true) { - return this.responseXML; - } - else - if (this.responseText === this._responseTextForResponseXML && this.responseXML) { - return this.responseXML; - } - - this.responseXML = _xjs(this.responseText); - this._responseTextForResponseXML = this.responseText; - return this.responseXML; - }, -/** -* This method can be used to set a number of default options for the Xmla instance. -* This is especially useful if you don't want to pass each and every option to each method call all the time. -* Where appropriate, information that is missing from the parameter objects passed to the methods of the Xmla object -* may be augmented with the values set through this method. -* For example, if you plan to do a series of requests pertaining to one particular datasource, -* you can set the mandatory options like url, async, datasource and catalog just once: -*
-    xmla.setOptions({
-        url: "http://localhost:8080/pentaho/Xmla",
-        async: true,
-        properties: {
-            DataSourceInfo: "Pentaho Analysis Services",
-            Catalog: "Foodmart"
-        }
-    });
-*    
-* Then, a subsequent -* @method setOptions -* @param Object -*/ - setOptions: function(options){ - _applyProps( - this.options, - options, - true + return doc; + }; + + /** + * + * The Xmla class provides a javascript API to communicate XML for Analysis (XML/A) over HTTP. + * XML/A is an industry standard protocol that allows webclients to work with OLAP servers. + * To fully understand the scope and purpose of this utility, it is highly recommended + * to read the XML/A specification + * (MS Word format. For other formats, + * see: http://code.google.com/p/xmla4js/source/browse/#svn/trunk/doc/xmla1.1 specification). + * + * The optional options parameter sets standard options for this Xmla instnace. + * If ommitted, a copy of the defaultOptions will be used. + * + * @class Xmla + * @constructor + * @param options Object standard options + */ + Xmla = function(options){ + + this.listeners = {}; + this.listeners[Xmla.EVENT_REQUEST] = []; + this.listeners[Xmla.EVENT_SUCCESS] = []; + this.listeners[Xmla.EVENT_ERROR] = []; + + this.listeners[Xmla.EVENT_DISCOVER] = []; + this.listeners[Xmla.EVENT_DISCOVER_SUCCESS] = []; + this.listeners[Xmla.EVENT_DISCOVER_ERROR] = []; + + this.listeners[Xmla.EVENT_EXECUTE] = []; + this.listeners[Xmla.EVENT_EXECUTE_SUCCESS] = []; + this.listeners[Xmla.EVENT_EXECUTE_ERROR] = []; + + this.options = _applyProps( + _applyProps({}, Xmla.defaultOptions, true), + options, true ); - }, -/** -* This method can be used to register one or more listeners. On such listener can listen for one or more events. -*

For a single listener, you can pass a listener object literal with the following structure:

{
-*       events: ...event name or array of event names...,
-*       handler: ...function or array of functions...,
-*       scope: object
-*   }
-*

-* You can use event as an alias for events. -* Likewise, you can use handlers as an alias for handler. -*

-*

-* Alternatively, you can pass the element as separate arguments instead of as an object literal: -* addListener(name, func, scope) -* where name is a valid event name, func is the function that is to be called when the event occurs. -* The last argument is optional and can be used to specify the scope that will be used as context for executing the function. -*

-*

-* To register multiple listeners, pass an array of listener objects: -* addListener([listener1, ..., listenerN]) -*

-*

-* Alternatively, pass multiple listener objects as separate arguments: -* addListener(listener1, ..., listenerN) -*

-*

-* Or, pass a single object literal with event names as keys and listener objects or functions as values: -*

addListener({
-*           discover: function() {
-*               ...handle discover event...
-*           },
-*           error: {
-*               handler: function() {
-*                  ...handle error event...
-*               },
-*               scope: obj
-*           },
-*           scope: defaultscope
-*       })
-* In this case, you can use scope as a key to specify the default scope for the handler functions. -*

-*

Below is a more detailed description of the listener object and its components:

-*
-*
events
-*
string|string[] REQUIRED. -* The event or events to listen to. -* You can specify a single event by using one of the EVENT_XXX string constant values. -* You can specify multiple events by using an array of EVENT_XXX string constant values. -* You can also use one of the predefined EVENT_XXX array constant values, -* or use array concatenation and compose a custom list of event names. -* To listen to all events, either use EVENT_ALL, -* or otherwise the string value "all". -* Below is the list of constants that may be used for the events or events property: -*
-*
event
-*
string|string[] Alias for events
-*
handler
-*
function|function[] REQUIRED. -* This function will be called and notified whenever one of the specified events occurs. -* The function has the following signature: boolean handler(string eventName, object eventData, Xmla xmla) -* You can also pass in an array of functions if you want multiple functions to be called when the event occurs. -* The function is called in scope of the scope property of the listener object. -* If no scope is specified, a global function is assumed. -* The handler function has the following arguments: -*
-*
eventName
-*
string The event for which notification is given. -* This is useful to distinguish between events in case the same handler function is used for multiple events. -* In this case, use the EVENT_XXX constants to check the eventName.
-*
eventData
-*
Object An object that conveys event-specific data.
-*
xmla
-*
Xmla A reference to this Xmla instance that is the source of the event. -* Listeners can obtain the response as well as the original SOAP message sent to the server through this instance. -* This allows one listener to be shared across multiple Xmla instances without managing the context manually. -*
-*
-* For events that are cancelable, the handler should return a boolean. -* If the handler returns false the respective operation will be canceled. -* Otherwise, the operation continues (but may be canceled by another handler). -* Currently, the following events are cancelable: -* EVENT_DISCOVER, -* EVENT_EXECUTE, and -* EVENT_REQUEST. -*
-*
handlers
-*
function|function[] Alias for handler
-*
scope
-*
Object OPTIONAL When specified, this object is used as the this object when calling the handler. -* When not specified, the global window is used. -*
-*
-* @method addListener -* @param {Object|Array} listener An object that defines the events and the notification function to be called, or an array of such objects. -*/ - addListener: function(){ - var n = arguments.length, handler, scope; - switch(n) { - case 0: + var listeners = this.options.listeners; + if (listeners) this.addListener(listeners); + return this; + }; + + /** + * These are the default options used for new Xmla instances in case no custom properties are set. + * It sets the following properties: + * + * + * @property defaultOptions + * @static + * @type object + **/ + Xmla.defaultOptions = { + requestTimeout: 30000, //by default, we bail out after 30 seconds + async: false, //by default, we do a synchronous request + addFieldGetters: true, //true to augment rowsets with a method to fetch a specific field. + //forceResponseXMLEmulation: true //true to use our own XML parser instead of XHR's native responseXML. Useful for testing. + forceResponseXMLEmulation: false //true to use our own XML parser instead of XHR's native responseXML. Useful for testing. + }; + + /** + * Can be used as value for the method option in the options object passed to the + * request() method to invoke the XML/A Discover method on the server. + * Instead of explicitly setting the method yourself, consider using the discover() method. + * The discover() method automatically sets the method option to METHOD_DISCOVER. + * @property METHOD_DISCOVER + * @static + * @final + * @type string + * @default Discover + */ + Xmla.METHOD_DISCOVER = "Discover"; + /** + * Can be used as value for the method option property in the options objecct passed to the + * request() method to invoke the XML/A Execute method on the server. + * Instead of explicitly setting the method yourself, consider using the execute() method. + * The execute() method automatically sets the method option to METHOD_EXECUTE. + * @property METHOD_EXECUTE + * @static + * @final + * @type string + * @default Discover + */ + Xmla.METHOD_EXECUTE = "Execute"; + + var _xmlaDISCOVER = "DISCOVER_"; + var _xmlaMDSCHEMA = "MDSCHEMA_"; + var _xmlaDBSCHEMA = "DBSCHEMA_"; + + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DISCOVER_DATASOURCES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this constant as requestType yourself, consider calling the discoverDataSources() method. + * The discoverDataSources() method passes DISCOVER_DATASOURCES automatically as requestType for Discover requests. + * + * @property DISCOVER_DATASOURCES + * @static + * @final + * @type string + * @default DISCOVER_DATASOURCES + */ + Xmla.DISCOVER_DATASOURCES = _xmlaDISCOVER + "DATASOURCES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DISCOVER_PROPERTIES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverProperties() method. + * The discoverProperties() method passes DISCOVER_PROPERTIES automatically as requestType for Discover requests. + * + * @property DISCOVER_PROPERTIES + * @static + * @final + * @type string + * @default DISCOVER_PROPERTIES + */ + Xmla.DISCOVER_PROPERTIES = _xmlaDISCOVER + "PROPERTIES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DISCOVER_SCHEMA_ROWSETS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverSchemaRowsets() method. + * The discoverProperties() method passes DISCOVER_PROPERTIES automatically as requestType for Discover requests. + * + * @property DISCOVER_SCHEMA_ROWSETS + * @static + * @final + * @type string + * @default DISCOVER_SCHEMA_ROWSETS + */ + Xmla.DISCOVER_SCHEMA_ROWSETS = _xmlaDISCOVER + "SCHEMA_ROWSETS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DISCOVER_ENUMERATORS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverEnumerators() method. + * The discoverSchemaRowsets() method issues a request to invoke the Discover method using DISCOVER_SCHEMA_ROWSETS as requestType. + * + * @property DISCOVER_ENUMERATORS + * @static + * @final + * @type string + * @default DISCOVER_ENUMERATORS + */ + Xmla.DISCOVER_ENUMERATORS = _xmlaDISCOVER + "ENUMERATORS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DISCOVER_KEYWORDS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverKeywords() method. + * The discoverKeywords() method issues a request to invoke the Discover method using DISCOVER_KEYWORDS as requestType. + * + * @property DISCOVER_KEYWORDS + * @static + * @final + * @type string + * @default DISCOVER_KEYWORDS + */ + Xmla.DISCOVER_KEYWORDS = _xmlaDISCOVER + "KEYWORDS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DISCOVER_LITERALS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverLiterals() method. + * The discoverLiterals() method issues a request to invoke the Discover method using DISCOVER_LITERALS as requestType. + * + * @property DISCOVER_LITERALS + * @static + * @final + * @type string + * @default DISCOVER_LITERALS + */ + Xmla.DISCOVER_LITERALS = _xmlaDISCOVER + "LITERALS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_CATALOGS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverDBCatalogs() method. + * The discoverDBCatalogs() method issues a request to invoke the Discover method using DBSCHEMA_CATALOGS as requestType. + * + * @property DBSCHEMA_CATALOGS + * @static + * @final + * @type string + * @default DBSCHEMA_CATALOGS + */ + Xmla.DBSCHEMA_CATALOGS = _xmlaDBSCHEMA + "CATALOGS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_COLUMNS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverDBColumns() method. + * The discoverDBColumns() method issues a request to invoke the Discover method using DBSCHEMA_COLUMNS as requestType. + * + * @property DBSCHEMA_COLUMNS + * @static + * @final + * @type string + * @default DBSCHEMA_COLUMNS + */ + Xmla.DBSCHEMA_COLUMNS = _xmlaDBSCHEMA + "COLUMNS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_PROVIDER_TYPES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverDBProviderTypes() method. + * The discoverDBProviderTypes() method issues a request to invoke the Discover method using DBSCHEMA_PROVIDER_TYPES as requestType. + * + * @property DBSCHEMA_PROVIDER_TYPES + * @static + * @final + * @type string + * @default DBSCHEMA_PROVIDER_TYPES + */ + Xmla.DBSCHEMA_PROVIDER_TYPES = _xmlaDBSCHEMA + "PROVIDER_TYPES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_SCHEMATA schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverDBSchemata() method. + * The discoverDBColumns() method issues a request to invoke the Discover method using DBSCHEMA_SCHEMATA as requestType. + * + * @property DBSCHEMA_SCHEMATA + * @static + * @final + * @type string + * @default DBSCHEMA_SCHEMATA + */ + Xmla.DBSCHEMA_SCHEMATA = _xmlaDBSCHEMA + "SCHEMATA"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_TABLES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the discoverDBTables() method. + * The discoverDBColumns() method issues a request to invoke the Discover method using DBSCHEMA_TABLES as requestType. + * + * @property DBSCHEMA_TABLES + * @static + * @final + * @type string + * @default DBSCHEMA_TABLES + */ + Xmla.DBSCHEMA_TABLES = _xmlaDBSCHEMA + "TABLES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the DBSCHEMA_TABLES_INFO schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverDBTablesInfo() method. + * The discoverDBTablesInfo() method issues a request to invoke the Discover method using DBSCHEMA_TABLES_INFO as requestType. + * + * @property DBSCHEMA_TABLES_INFO + * @static + * @final + * @type string + * @default DBSCHEMA_TABLES_INFO + */ + Xmla.DBSCHEMA_TABLES_INFO = _xmlaDBSCHEMA + "TABLES_INFO"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the MDSCHEMA_ACTIONS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDActions() method. + * The discoverMDActions() method issues a request to invoke the Discover method using MDSCHEMA_ACTIONS as requestType. + * + * @property MDSCHEMA_ACTIONS + * @static + * @final + * @type string + * @default MDSCHEMA_ACTIONS + */ + Xmla.MDSCHEMA_ACTIONS = _xmlaMDSCHEMA + "ACTIONS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_CUBES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDCubes() method. + * The discoverMDCubes() method issues a request to invoke the Discover method using + * MDSCHEMA_CUBES as requestType. + * + * @property MDSCHEMA_CUBES + * @static + * @final + * @type string + * @default MDSCHEMA_CUBES + */ + Xmla.MDSCHEMA_CUBES = _xmlaMDSCHEMA + "CUBES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_DIMENSIONS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDDimensions() method. + * The discoverMDDimensions() method issues a request to invoke the Discover method using + * MDSCHEMA_DIMENSIONS as requestType. + * + * @property MDSCHEMA_DIMENSIONS + * @static + * @final + * @type string + * @default MDSCHEMA_DIMENSIONS + */ + Xmla.MDSCHEMA_DIMENSIONS = _xmlaMDSCHEMA + "DIMENSIONS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_FUNCTIONS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDFunctions() method. + * The discoverMDFunctions() method issues a request to invoke the Discover method using + * MDSCHEMA_FUNCTIONS as requestType. + * + * @property MDSCHEMA_FUNCTIONS + * @static + * @final + * @type string + * @default MDSCHEMA_FUNCTIONS + */ + Xmla.MDSCHEMA_FUNCTIONS = _xmlaMDSCHEMA + "FUNCTIONS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_HIERARCHIES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDHierarchies() method. + * The discoverMDHierarchies() method issues a request to invoke the Discover method using + * MDSCHEMA_HIERARCHIES as requestType. + * + * @property MDSCHEMA_HIERARCHIES + * @static + * @final + * @type string + * @default MDSCHEMA_HIERARCHIES + */ + Xmla.MDSCHEMA_HIERARCHIES = _xmlaMDSCHEMA + "HIERARCHIES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_LEVELS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDLevels() method. + * The discoverMDLevels() method issues a request to invoke the Discover method using + * MDSCHEMA_LEVELS as requestType. + * + * @property MDSCHEMA_LEVELS + * @static + * @final + * @type string + * @default MDSCHEMA_LEVELS + */ + Xmla.MDSCHEMA_LEVELS = _xmlaMDSCHEMA + "LEVELS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_MEASURES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDMeasures() method. + * The discoverMDMeasures() method issues a request to invoke the Discover method using + * MDSCHEMA_MEASURES as requestType. + * + * @property MDSCHEMA_MEASURES + * @static + * @final + * @type string + * @default MDSCHEMA_MEASURES + */ + Xmla.MDSCHEMA_MEASURES = _xmlaMDSCHEMA + "MEASURES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_MEMBERS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDMembers() method. + * The discoverMDMembers() method issues a request to invoke the Discover method using + * MDSCHEMA_MEMBERS as requestType. + * + * @property MDSCHEMA_MEMBERS + * @static + * @final + * @type string + * @default MDSCHEMA_MEMBERS + */ + Xmla.MDSCHEMA_MEMBERS = _xmlaMDSCHEMA + "MEMBERS"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_PROPERTIES schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDProperties() method. + * The discoverMDProperties() method issues a request to invoke the Discover method using + * MDSCHEMA_PROPERTIES as requestType. + * + * @property MDSCHEMA_PROPERTIES + * @static + * @final + * @type string + * @default MDSCHEMA_PROPERTIES + */ + Xmla.MDSCHEMA_PROPERTIES = _xmlaMDSCHEMA + "PROPERTIES"; + /** + * Can be used as value for the requestType option in the options object passed to the to + * request() method to invoke the XML/A Discover method on the server to return the + * MDSCHEMA_SETS schema rowset. + * The requestType option applies only to Discover requests. + * Instead of passing this requestType yourself, consider calling the + * discoverMDSets() method. + * The discoverMDSets() method issues a request to invoke the Discover method using + * MDSCHEMA_SETS as requestType. + * + * @property MDSCHEMA_SETS + * @static + * @final + * @type string + * @default MDSCHEMA_SETS + */ + Xmla.MDSCHEMA_SETS = _xmlaMDSCHEMA + "SETS"; + /** + * Indicates the request event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The request event is the first event that is fired before submitting a request + * (see: request()) + * to the server, and before firing the method-specific request events + * (see EVENT_EXECUTE + * and EVENT_DISCOVER). + * The request event itself is not method-specific, and fires for Execute as well as Discover requests. + * The EVENT_REQUEST event is cancelable: + * the handler function specified in the listener object passed to addListener should return a boolen, indicating + * whether the respective operation should be canceled. + * + * @property EVENT_REQUEST + * @static + * @final + * @type string + * @default request + */ + Xmla.EVENT_REQUEST = "request"; + /** + * Indicates the success event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The success event is the last event that is fired after receiving and processing a normal response + * (that is, a response that does not contain an XML/A SoapFault), + * after firing the method-specific success events + * (see EVENT_EXECUTE_SUCCESS + * and EVENT_DISCOVER_SUCCESS). + * The success event is not method-specific, and fires for Execute as well as Discover responses. + * This is event is not cancelable. + * + * @property EVENT_SUCCESS + * @static + * @final + * @type string + * @default success + */ + Xmla.EVENT_SUCCESS = "success"; + /** + * Indicates the error event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The error is fired when an error occurs while sending a request or receiving a response. + * The error event is not method-specific, and fires for errors encountered during both Execute as well as Discover method invocations. + * This is event is not cancelable. + * + * @property EVENT_ERROR + * @static + * @final + * @type string + * @default error + */ + Xmla.EVENT_ERROR = "error"; + + /** + * Indicates the execute event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The execute event is method-specific, and is fired before submitting an Execute request + * (see: execute()) + * to the server, but after firing the request event + * (see: EVENT_REQUEST). + * The EVENT_EXECUTE event is cancelable: + * the handler function specified in the listener object passed to addListener should return a boolen, indicating + * whether the respective operation should be canceled. + * + * @property EVENT_EXECUTE + * @static + * @final + * @type string + * @default execute + */ + Xmla.EVENT_EXECUTE = "execute"; + /** + * Indicates the executesuccess event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The executesuccess event is method-specific and fired only after receiving and processing a normal response + * (that is, a response that does not contain a SoapFault) + * to an incovation of the XML/A Execute method + * (see: execute()). + * This is event is not cancelable. + * + * @property EVENT_EXECUTE_SUCCESS + * @static + * @final + * @type string + * @default executesuccess + */ + Xmla.EVENT_EXECUTE_SUCCESS = "executesuccess"; + /** + * Indicates the executeerror event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The executeerror event is method-specific and fired when an error occurs while sending an Execute request, or receiving a response to an Execute method. + * (see: execute()). + * This is event is not cancelable. + * + * @property EVENT_EXECUTE_ERROR + * @static + * @final + * @type string + * @default executeerror + */ + Xmla.EVENT_EXECUTE_ERROR = "executeerror"; + + /** + * Indicates the discover event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The discover event is method-specific, and is fired before submitting a Discover request + * (see: discover()) + * to the server, but after firing the request event + * (see: EVENT_DISCOVER). + * The EVENT_DISCOVER event is cancelable: + * the handler function specified in the listener object passed to addListener should return a boolen, indicating + * whether the respective operation should be canceled. + * + * @property EVENT_DISCOVER + * @static + * @final + * @type string + * @default discover + */ + Xmla.EVENT_DISCOVER = "discover"; + /** + * Indicates the discoversuccess event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The discoversuccess event is method-specific and fired only after receiving and processing a normal response + * (that is, a response that does not contain a SoapFault) + * to an incovation of the XML/A Discover method + * (see: discover()). + * This is event is not cancelable. + * + * @property EVENT_DISCOVER_SUCCESS + * @static + * @final + * @type string + * @default discoversuccess + */ + Xmla.EVENT_DISCOVER_SUCCESS = "discoversuccess"; + /** + * Indicates the discovererror event. + * This constant can be used as en entry in the events array argument for the addListener() method. + * The discovererror is method-specific and fired when an error occurs while sending an Discover request, + * or receiving a response to an Discover method. + * (see: discover()). + * This is event is not cancelable. + * + * @property EVENT_DISCOVER_ERROR + * @static + * @final + * @type string + * @default discovererror + */ + Xmla.EVENT_DISCOVER_ERROR = "discovererror"; + + /** + * Unifies all general events, that is, all events that are not method-specific. + * This constant can be used as events array argument for the addListener() method, + * or you can use array concatenation to combine it with other arrays of EVENT_XXX constants. + * This constant is especially intended for asyncronous handling of Schema rowset data. + * + * @property EVENT_GENERAL + * @static + * @final + * @type string[] + * @default [EVENT_REQUEST,EVENT_SUCCESS,EVENT_ERROR] + */ + Xmla.EVENT_GENERAL = [ + Xmla.EVENT_REQUEST, + Xmla.EVENT_SUCCESS, + Xmla.EVENT_ERROR + ]; + + /** + * Unifies all events specific for the Discover method. + * This constant can be used as events array argument for the addListener() method, + * or you can use array concatenation to combine it with other arrays of EVENT_XXX constants. + * + * @property EVENT_DISCOVER_ALL + * @static + * @final + * @type string[] + * @default [EVENT_DISCOVER,EVENT_DISCOVER_SUCCESS,EVENT_DISCOVER_ERROR] + */ + Xmla.EVENT_DISCOVER_ALL = [ + Xmla.EVENT_DISCOVER, + Xmla.EVENT_DISCOVER_SUCCESS, + Xmla.EVENT_DISCOVER_ERROR + ]; + + /** + * Unifies all events specific for the Execute method. + * This constant can be used as events array argument for the addListener() method, + * or you can use array concatenation to combine it with other arrays of EVENT_XXX constants. + * + * @property EVENT_EXECUTE_ALL + * @static + * @final + * @type string[] + * @default [EVENT_EXECUTE,EVENT_EXECUTE_SUCCESS,EVENT_EXECUTE_ERROR] + */ + Xmla.EVENT_EXECUTE_ALL = [ + Xmla.EVENT_EXECUTE, + Xmla.EVENT_EXECUTE_SUCCESS, + Xmla.EVENT_EXECUTE_ERROR + ]; + + /** + * Unifies all method-specific and non method-specific events. + * This constant can be used as events array argument for the addListener() method. + * + * @property EVENT_ALL + * @static + * @final + * @type string[] + * @default [].concat(Xmla.EVENT_GENERAL, Xmla.EVENT_DISCOVER_ALL, Xmla.EVENT_EXECUTE_ALL) + */ + Xmla.EVENT_ALL = [].concat( + Xmla.EVENT_GENERAL, + Xmla.EVENT_DISCOVER_ALL, + Xmla.EVENT_EXECUTE_ALL + ); + + /** + * Can be used as key in the properties member of the options object + * passed to the request() method + * to specify the XML/A DataSourceInfo property. + * The XML/A DataSourceInfo, together with the XML/A service URL are required to + * connect to a particular OLAP datasource. + * Valid values for the DataSourceInfo as well as the corresponding URL should be obtained + * by querying the DataSourceInfo and URL columns of the DISCOVER_DATASOURCES + * rowset respectively (see discoverDataSources()). + * + * @property PROP_DATASOURCEINFO + * @static + * @final + * @type string + * @default DataSourceInfo + */ + Xmla.PROP_DATASOURCEINFO = "DataSourceInfo"; + /** + * Can be used as key in the properties member of the options object + * passed to the execute() method + * to specify the XML/A Catalog property. + * The XML/A Catalog spefifies where to look for cubes that are referenced in th MDX statment. + * Valid values for the Catalog should be obtained + * by querying the CATALOG_NAME of the DBSCHEMA_CATALOGS + * rowset (see discoverDBCatalogs()). + * + * @property PROP_Catalog + * @static + * @final + * @type string + * @default Catalog + */ + Xmla.PROP_CATALOG = "Catalog"; + Xmla.PROP_CUBE = "Cube"; + + /** + * Can be used as key in the properties member of the options object + * passed to the execute() method + * to specify the XML/A Format property. + * This property controls the structure of the resultset. + * + * @property PROP_FORMAT + * @static + * @final + * @type string + * @default Format + */ + Xmla.PROP_FORMAT = "Format"; + /** + * Can be used as value for the + * execute() method. + * When used, this specifies that the multidimensional resultset should be returned in a tabular format, + * causeing the multidimensional resultset to be represented with an instance of the + * Xmla.Rowset class. + * + * @property PROP_FORMAT_TABULAR + * @static + * @final + * @type string + * @default Tabular + */ + Xmla.PROP_FORMAT_TABULAR = "Tabular"; + /** + * Can be used as value for the + * execute() method. + * When used, this specifies that the multidimensional resultset should be returned in a multidimensional format. + * Currently, Xmla4js does not provide a class to represent the resultset in this format. + * However, you can access the results as xml through the + * responseText and + * responseXML properties. + * + * @property PROP_FORMAT_MULTIDIMENSIONAL + * @static + * @final + * @type string + * @default Multidimensional + */ + Xmla.PROP_FORMAT_MULTIDIMENSIONAL = "Multidimensional"; + + /** + * Can be used as key in the properties member of the options object + * passed to the execute() method + * to specify the XML/A AxisFormat property. + * The XML/A AxisFormat property specifies how the client wants to receive the multi-dimensional resultset of a MDX query. + * Valid values for the AxisFormat property are available as the static final properties + * PROP_AXISFORMAT_TUPLE, + * PROP_AXISFORMAT_CLUSTER, + * PROP_AXISFORMAT_CUSTOM. + * + * @property PROP_AXISFORMAT + * @static + * @final + * @type string + * @default AxisFormat + */ + Xmla.PROP_AXISFORMAT = "AxisFormat"; + /** + * Can be used as value for the AxisFormat XML/A property + * (see: PROP_AXISFORMAT) + * in invocations of the Execute method + * (see: execute()). + * + * @property PROP_AXISFORMAT_TUPLE + * @static + * @final + * @type string + * @default TupleFormat + */ + Xmla.PROP_AXISFORMAT_TUPLE = "TupleFormat"; + /** + * Can be used as value for the AxisFormat XML/A property + * (see: PROP_AXISFORMAT) + * in invocations of the Execute method + * (see: execute()). + * + * @property PROP_AXISFORMAT_CLUSTER + * @static + * @final + * @type string + * @default ClusterFormat + */ + Xmla.PROP_AXISFORMAT_CLUSTER = "ClusterFormat"; + /** + * Can be used as value for the AxisFormat XML/A property + * (see: PROP_AXISFORMAT) + * in invocations of the Execute method + * (see: execute()). + * + * @property PROP_AXISFORMAT_CUSTOM + * @static + * @final + * @type string + * @default CustomFormat + */ + Xmla.PROP_AXISFORMAT_CUSTOM = "CustomFormat"; + + /** + * Can be used as key in the properties member of the options object + * passed to the request() method + * to specify the XML/A Content property. + * The XML/A Content property specifies whether to return data and/or XML Schema metadata by the Discover and Execute invocations. + * Valid values for the Content property are available as the static final properties + * PROP_CONTENT_DATA, + * PROP_CONTENT_NONE, + * PROP_CONTENT_SCHEMA, + * PROP_CONTENT_SCHEMADATA. + * + * Note: This key is primarily intended for clients that use the low-level request() method. + * You should not set this property when calling the discover() method, + * the execute() method, + * or any of the discoverXXX() methods. + * + * @property PROP_CONTENT + * @static + * @final + * @type string + * @default Content + */ + Xmla.PROP_CONTENT = "Content"; + /** + * Can be used as value for the XML/A Content property + * (see: PROP_CONTENT). + * This value specifies that the response should contain only data, but no XML Schema metadata. + * + * As the Xmla class relies on the XML Schema metadata to construct Rowset and Resultset instances, + * this option is primarily useful if you know how to process the XML response directly. + * + * @property PROP_CONTENT_DATA + * @static + * @final + * @type string + * @default Data + */ + Xmla.PROP_CONTENT_DATA = "Data"; + /** + * Can be used as value for the XML/A Content property + * (see: PROP_CONTENT). + * This value specifies that the response should contain neither data nor XML Schema metadata. + * This is useful to check the validity of the request. + * + * @property PROP_CONTENT_NONE + * @static + * @final + * @type string + * @default None + */ + Xmla.PROP_CONTENT_NONE = "None"; + /** + * Can be used as value for the XML/A Content property + * (see: PROP_CONTENT). + * This value specifies that the response should only return XML Schema metadata, but no data. + * + * @property PROP_CONTENT_SCHEMA + * @static + * @final + * @type string + * @default Schema + */ + Xmla.PROP_CONTENT_SCHEMA = "Schema"; + /** + * Can be used as value for the XML/A Content property + * (see: PROP_CONTENT). + * This value specifies that the response should return both data as well as XML Schema metadata. + * + * @property PROP_CONTENT_SCHEMADATA + * @static + * @final + * @type string + * @default SchemaData + */ + Xmla.PROP_CONTENT_SCHEMADATA = "SchemaData"; + + Xmla.prototype = { + /** + * This object stores listeners. + * Each key is a listener type (see the static final EVENT_XXX constants), + * each value is an array of listener objects that are subscribed to that particular event. + * + * @property listeners + * @protected + * @type Object + * @default
+    {
+          "request": []
+     ,   "succss": []
+     ,   "error": []
+     ,   "discover": []
+     ,   "discoversuccss": []
+     ,   "discovererror": []
+     ,   "execute": []
+     ,   "executesuccss": []
+     ,   "executeerror": []
+    }
+ */ + listeners: null, + /** + * The soap message sent in the last request to the server. + * + * @property soapMessage + * @type {string} + * @default null + */ + soapMessage: null, + /** + * This property is set to null right before sending an XML/A request. + * When a successfull response is received, it is processed and the response object is assigned to this property. + * The response object is either a + * Rowset (after a successful invocation of XML/A Discover method, see: discover()) or a + * Resultset (after a successful invocation of the XML/A Execute method, see: execute()) + * instance. + * + * If you are interested in processing the raw response XML, see + * responseXML and + * responseText. + * + * Note that it is not safe to read this property immediately after doing an asynchronous request. + * For asynchronous requests, you can read this property by the time the XXX_SUCCESS event handlers are notified (until it is set to null again by a subsequent request). + * + * @property response + * @type Xmla.Rowset|Xmla.Dataset + * @default null + */ + response: null, + /** + * This property is set to null right before sending an XML/A request. + * When a successfull response is received, the XML response is stored to this property as plain text. + * + * If you are interested in processing a DOM document rather than the raw XML text, see the + * responseXML property. + * + * If you are interested in traversing the dataset returned in the XML/A response, see the + * response property. + * + * Note that it is not safe to read this property immediately after doing an asynchronous request. + * For asynchronous requests, you can read this property by the time the XXX_SUCCESS event handlers are notified (until it is set to null again by a subsequent request). + * + * @property responseText + * @type {string} + * @default null + */ + responseText: null, + /** + * This property is set to null right before sending an XML/A request. + * When a successfull response is received, the XML response is stored to this property as a DOM Document. + * + * If you are interested in processing the raw XML text rather than a DOM document, see the + * responseText property. + * + * If you are interested in traversing the dataset returned in the XML/A response, see the + * response property. + * + * Note that it is not safe to read this property immediately after doing an asynchronous request. + * For asynchronous requests, you can read this property by the time the XXX_SUCCESS event handlers are notified (until it is set to null again by a subsequent request). + * + * @deprecated + * @property responseXML + * @type {DOMDocument} + * @default null + * @see getRep + */ + responseXML: null, + /** + * @method getResponseXML + * @return {DOMDocument} + */ + getResponseXML: function(){ + if (this.options.forceResponseXMLEmulation !== true) { + return this.responseXML; + } + else + if (this.responseText === this._responseTextForResponseXML && this.responseXML) { + return this.responseXML; + } + + this.responseXML = _xjs(this.responseText); + this._responseTextForResponseXML = this.responseText; + return this.responseXML; + }, + /** + * This method can be used to set a number of default options for the Xmla instance. + * This is especially useful if you don't want to pass each and every option to each method call all the time. + * Where appropriate, information that is missing from the parameter objects passed to the methods of the Xmla object + * may be augmented with the values set through this method. + * For example, if you plan to do a series of requests pertaining to one particular datasource, + * you can set the mandatory options like url, async, datasource and catalog just once: + *
+        xmla.setOptions({
+            url: "http://localhost:8080/pentaho/Xmla",
+            async: true,
+            properties: {
+                DataSourceInfo: "Pentaho Analysis Services",
+                Catalog: "Foodmart"
+            }
+        });
+    *    
+ * Then, a subsequent + * @method setOptions + * @param Object + */ + setOptions: function(options){ + _applyProps( + this.options, + options, + true + ); + }, + /** + * This method can be used to register one or more listeners. On such listener can listen for one or more events. + *

For a single listener, you can pass a listener object literal with the following structure:

{
+    *       events: ...event name or array of event names...,
+    *       handler: ...function or array of functions...,
+    *       scope: object
+    *   }
+ *

+ * You can use event as an alias for events. + * Likewise, you can use handlers as an alias for handler. + *

+ *

+ * Alternatively, you can pass the element as separate arguments instead of as an object literal: + * addListener(name, func, scope) + * where name is a valid event name, func is the function that is to be called when the event occurs. + * The last argument is optional and can be used to specify the scope that will be used as context for executing the function. + *

+ *

+ * To register multiple listeners, pass an array of listener objects: + * addListener([listener1, ..., listenerN]) + *

+ *

+ * Alternatively, pass multiple listener objects as separate arguments: + * addListener(listener1, ..., listenerN) + *

+ *

+ * Or, pass a single object literal with event names as keys and listener objects or functions as values: + *

addListener({
+    *           discover: function() {
+    *               ...handle discover event...
+    *           },
+    *           error: {
+    *               handler: function() {
+    *                  ...handle error event...
+    *               },
+    *               scope: obj
+    *           },
+    *           scope: defaultscope
+    *       })
+ * In this case, you can use scope as a key to specify the default scope for the handler functions. + *

+ *

Below is a more detailed description of the listener object and its components:

+ *
+ *
events
+ *
string|string[] REQUIRED. + * The event or events to listen to. + * You can specify a single event by using one of the EVENT_XXX string constant values. + * You can specify multiple events by using an array of EVENT_XXX string constant values. + * You can also use one of the predefined EVENT_XXX array constant values, + * or use array concatenation and compose a custom list of event names. + * To listen to all events, either use EVENT_ALL, + * or otherwise the string value "all". + * Below is the list of constants that may be used for the events or events property: + *
+ *
event
+ *
string|string[] Alias for events
+ *
handler
+ *
function|function[] REQUIRED. + * This function will be called and notified whenever one of the specified events occurs. + * The function has the following signature: boolean handler(string eventName, object eventData, Xmla xmla) + * You can also pass in an array of functions if you want multiple functions to be called when the event occurs. + * The function is called in scope of the scope property of the listener object. + * If no scope is specified, a global function is assumed. + * The handler function has the following arguments: + *
+ *
eventName
+ *
string The event for which notification is given. + * This is useful to distinguish between events in case the same handler function is used for multiple events. + * In this case, use the EVENT_XXX constants to check the eventName.
+ *
eventData
+ *
Object An object that conveys event-specific data.
+ *
xmla
+ *
Xmla A reference to this Xmla instance that is the source of the event. + * Listeners can obtain the response as well as the original SOAP message sent to the server through this instance. + * This allows one listener to be shared across multiple Xmla instances without managing the context manually. + *
+ *
+ * For events that are cancelable, the handler should return a boolean. + * If the handler returns false the respective operation will be canceled. + * Otherwise, the operation continues (but may be canceled by another handler). + * Currently, the following events are cancelable: + * EVENT_DISCOVER, + * EVENT_EXECUTE, and + * EVENT_REQUEST. + *
+ *
handlers
+ *
function|function[] Alias for handler
+ *
scope
+ *
Object OPTIONAL When specified, this object is used as the this object when calling the handler. + * When not specified, the global window is used. + *
+ *
+ * @method addListener + * @param {Object|Array} listener An object that defines the events and the notification function to be called, or an array of such objects. + */ + addListener: function(){ + var n = arguments.length, handler, scope; + switch(n) { + case 0: + Xmla.Exception._newError( + "NO_EVENTS_SPECIFIED", + "Xmla.addListener", + null + )._throw(); + case 1: + var arg = arguments[0]; + if (_isObj(arg)) { + var events; + if (_isArr(arg)) this._addListeners(arg) + else + if (events = arg.events || arg.event) { + if (_isStr(events)) events = (events === "all") ? Xmla.EVENT_ALL : events.split(","); + if (!(_isArr(events))){ + Xmla.Exception._newError( + "WRONG_EVENTS_FORMAT", + "Xmla.addListener", + arg + )._throw(); + } + var i; + n = events.length; + for (i = 0; i < n; i++) this._addListener(events[i], arg); + } + else { + scope = arg.scope; + if (_isUnd(scope)) scope = null; + else delete arg.scope; + for (events in arg) { + handler = arg[events]; + if (_isUnd(handler.scope)) handler.scope = scope; + this._addListener(events, handler); + } + } + } + else + Xmla.Exception._newError( + "WRONG_EVENTS_FORMAT", + "Xmla.addListener", + arg + )._throw(); + break; + case 2: + case 3: + var event = arguments[0]; + scope = arguments[2]; + handler = arguments[1]; + if (_isStr(event) && (_isFun(handler)||(_isObj(handler)))) this._addListener(event, handler, scope); + else { + var arr = [event, handler]; + if (scope) arr.push(scope); + this.addListener(arr); + } + break; + default: + this._addListeners(arguments); + } + }, + _addListeners: function(listeners) { + var i, n = listeners.length; + for (i = 0; i < n; i++) this.addListener(listeners[i]); + }, + _addListener: function(name, handler, scope) { + var myListeners = this.listeners[name]; + if (!myListeners) Xmla.Exception._newError( - "NO_EVENTS_SPECIFIED", + "UNKNOWN_EVENT", "Xmla.addListener", - null + {event: name, handler: handler, scope: scope} )._throw(); - case 1: - var arg = arguments[0]; - if (_isObj(arg)) { - var events; - if (_isArr(arg)) this._addListeners(arg) + if (!scope) scope = null; + switch (typeof(handler)) { + case "function": + myListeners.push({handler: handler, scope: scope}); + break; + case "object": + var handlers = handler.handler || handler.handlers; + if (handler.scope) scope = handler.scope; + if (_isFun(handlers)) { + myListeners.push({handler: handlers, scope: scope}); + } else - if (events = arg.events || arg.event) { - if (_isStr(events)) events = (events === "all") ? Xmla.EVENT_ALL : events.split(","); - if (!(_isArr(events))){ - Xmla.Exception._newError( - "WRONG_EVENTS_FORMAT", - "Xmla.addListener", - arg - )._throw(); - } - var i; - n = events.length; - for (i = 0; i < n; i++) this._addListener(events[i], arg); + if (_isArr(handlers)) { + var i, n = handlers.length; + for (i = 0; i < n; i++) this._addListener(name, handlers[i], scope); } - else { - scope = arg.scope; - if (_isUnd(scope)) scope = null; - else delete arg.scope; - for (events in arg) { - handler = arg[events]; - if (_isUnd(handler.scope)) handler.scope = scope; - this._addListener(events, handler); - } + break; + } + }, + _fireEvent: function(eventName, eventData, cancelable){ + var listeners = this.listeners[eventName]; + if (!listeners) { + Xmla.Exception._newError( + "UNKNOWN_EVENT", + "Xmla._fireEvent", + eventName + )._throw(); + } + var n = listeners.length, outcome = true; + if (n) { + var listener, listenerResult, i; + for (i = 0; i < n; i++){ + listener = listeners[i]; + listenerResult = listener.handler.call( + listener.scope, + eventName, + eventData, + this + ); + if (cancelable && listenerResult===false){ + outcome = false; + break; } } - else - Xmla.Exception._newError( - "WRONG_EVENTS_FORMAT", - "Xmla.addListener", - arg - )._throw(); + } + else //if there is neither a listener nor an error nor a general callback we explicitly throw the exception. + if (eventName === Xmla.EVENT_ERROR && !_isFun(eventData.error) && !_isFun(eventData.callback)) eventData.exception._throw(); + return outcome; + }, + /** + * Create a XML/A SOAP message that may be used as message body for a XML/A request + * @method getXmlaSoapMessage + * @param {object} options An object representing the message. The object can have these properties: + * @return {string} The SOAP message. + **/ + getXmlaSoapMessage: function getXmlaSoapMessage(options){ + var method = options.method, + msg = "" + + "\n<" + _xmlnsSOAPenvelopePrefix + ":Envelope" + + " " + _xmlnsIsSOAPenvelope + + " " + _SOAPencodingStyle + ">" + + "\n <" + _xmlnsSOAPenvelopePrefix + ":Body>" + + "\n <" + method + " " + _xmlnsIsXmla + " " + _SOAPencodingStyle + ">" + ; + switch(method){ + case Xmla.METHOD_DISCOVER: + if (!options.requestType) { + Xmla.Exception._newError( + "MISSING_REQUEST_TYPE", + "Xmla._getXmlaSoapMessage", + options + )._throw(); + } + msg += "\n <" + _xmlRequestType + ">" + options.requestType + "" + + _getXmlaSoapList("Restrictions", "RestrictionList", options.restrictions, " ") + + _getXmlaSoapList("Properties", "PropertyList", options.properties, " "); + break; + case Xmla.METHOD_EXECUTE: + if (!options.statement){ + Xmla.Exception._newError( + "MISSING_REQUEST_TYPE", + "Xmla._getXmlaSoapMessage", + options + )._throw(); + } + msg += "\n " + + "\n " + _xmlEncode(options.statement) + "" + + "\n " + + _getXmlaSoapList("Properties", "PropertyList", options.properties, " ") + ; + break; + default: + //we used to throw an exception here, + //but this would make it impossible + //to execute service or provider specific methods. + } + msg += "\n " + + "\n " + + "\n" + ; + return msg; + }, + /** + * Sends a request to the XML/A server. + * This method is rather low-level and allows full control over the request + * by passing an options object. General properties of the options object are: + * + * Other parts of the options object are method-specific. + * + * Instead of calling this method directly, consider calling + * discover() (to obtain a schema rowset), + * execute() (to issue a MDX query), + * or one of the specialized discoverXXX() methods (to obtain a particular schema rowset). + * @method request + * @param {Object} options An object whose properties convey the options for the request. + * @return {Xmla.Rowset|Xmla.Dataset} The result of the invoking the XML/A method. For an asynchronous request, the return value is not defined. For synchronous requests, Discover requests return an instance of a Xmla.Rowset, and Execute results return an instance of a Xmla.Dataset. + */ + request: function(options){ + var ex, xmla = this; + + this.response = null; + this.responseText = null; + this.responseXML = null; + + options = _applyProps(options, this.options, false); + if (!options.url){ + ex = Xmla.Exception._newError( + "MISSING_URL", + "Xmla.request", + options + ); + ex._throw(); + } + options.properties = _applyProps(options.properties, this.options.properties, false); + options.restrictions = _applyProps(options.restrictions, this.options.restrictions, false); + delete options.exception; + + if ( + !this._fireEvent(Xmla.EVENT_REQUEST, options, true) || + (options.method == Xmla.METHOD_DISCOVER && !this._fireEvent(Xmla.EVENT_DISCOVER, options)) || + (options.method == Xmla.METHOD_EXECUTE && !this._fireEvent(Xmla.EVENT_EXECUTE, options)) + ){ + return false; + } + + var soapMessage = this.getXmlaSoapMessage(options); + this.soapMessage = soapMessage; + var myXhr; + var ajaxOptions = { + async: options.async, + timeout: options.requestTimeout, + data: soapMessage, + error: function(exception){ + options.exception = exception; + xmla._requestError(options, exception); + }, + complete: function(xhr){ + options.xhr = xhr; + xmla._requestSuccess(options); + }, + url: options.url + }; + if (options.username) { + ajaxOptions.username = options.username; + } + if (options.password) { + ajaxOptions.password = options.password; + } + + var headers = {}; + if (this.options.headers) { + headers = _applyProps(headers, this.options.headers); + } + if (options.headers) { + headers = _applyProps(headers, options.headers, true); + } + ajaxOptions.headers = headers; + + myXhr = _ajax(ajaxOptions); + return this.response; + }, + _requestError: function(options, exception) { + if (options.error) { + options.error.call(options.scope ? options.scope : null, this, options, exception); + } + if (options.callback) { + options.callback.call(options.scope ? options.scope : null, Xmla.EVENT_ERROR, this, options, exception); + } + this._fireEvent(Xmla.EVENT_ERROR, options); + }, + //https://msdn.microsoft.com/en-us/library/ms187142.aspx#handling_soap_faults + _parseSoapFault: function(soapFault){ + //Get faultactor, faultstring, faultcode and detail elements + function _parseSoapFaultDetail(detailNode){ + var errors = []; + var i, childNodes = detailNode.childNodes, n = childNodes.length, childNode; + for (i = 0; i < n; i++) { + childNode = childNodes[i]; + if (childNode.nodeType !== 1) { + continue; + } + switch (childNode.nodeName){ + case "Error": + errors.push({ + ErrorCode: _getAttribute(childNode, "ErrorCode"), + Description: _getAttribute(childNode, "Description"), + Source: _getAttribute(childNode, "Source"), + HelpFile: _getAttribute(childNode, "HelpFile") + }); + break; + default: + } + } + return errors; + } + + var fields = {}, field, nodeName; + var i, childNodes = soapFault.childNodes, n = childNodes.length, childNode; + for (i = 0; i < n; i++){ + childNode = childNodes[i]; + if (childNode.nodeType !== 1) { + continue; + } + nodeName = childNode.nodeName; + switch (nodeName) { + case "faultactor": + case "faultstring": + case "faultcode": + field = _getElementText(childNode); break; - case 2: - case 3: - var event = arguments[0]; - scope = arguments[2]; - handler = arguments[1]; - if (_isStr(event) && (_isFun(handler)||(_isObj(handler)))) this._addListener(event, handler, scope); - else { - var arr = [event, handler]; - if (scope) arr.push(scope); - this.addListener(arr); - } + case "detail": + field = _parseSoapFaultDetail(childNode); break; - default: - this._addListeners(arguments); - } - }, - _addListeners: function(listeners) { - var i, n = listeners.length; - for (i = 0; i < n; i++) this.addListener(listeners[i]); - }, - _addListener: function(name, handler, scope) { - var myListeners = this.listeners[name]; - if (!myListeners) - Xmla.Exception._newError( - "UNKNOWN_EVENT", - "Xmla.addListener", - {event: name, handler: handler, scope: scope} - )._throw(); - if (!scope) scope = null; - switch (typeof(handler)) { - case "function": - myListeners.push({handler: handler, scope: scope}); + default: + field = null; break; - case "object": - var handlers = handler.handler || handler.handlers; - if (handler.scope) scope = handler.scope; - if (_isFun(handlers)) { - myListeners.push({handler: handlers, scope: scope}); + } + if (field) { + fields[nodeName] = field; + } + } + return fields; + }, + _requestSuccess: function(request) { + var xhr = request.xhr, response; + if (request.forceResponseXMLEmulation !== true) { + this.responseXML = xhr.responseXML; + } + this.responseText = xhr.responseText; + + var method = request.method; + + try { + var responseXml = this.getResponseXML(); + if (!responseXml) { + request.exception = new Xmla.Exception( + Xmla.Exception.TYPE_ERROR, + Xmla.Exception.ERROR_PARSING_RESPONSE_CDE, + "Response is not an XML document." + ); } - else - if (_isArr(handlers)) { - var i, n = handlers.length; - for (i = 0; i < n; i++) this._addListener(name, handlers[i], scope); + var soapFault = _getElementsByTagNameNS(responseXml, _xmlnsSOAPenvelope, _xmlnsSOAPenvelopePrefix, "Fault"); + if (soapFault.length) { + //TODO: extract error info + soapFault = soapFault[0]; + soapFault = this._parseSoapFault(soapFault); + //type, code, message, helpfile, source, data, args, detail, actor + request.exception = new Xmla.Exception( + Xmla.Exception.TYPE_ERROR, + soapFault.faultcode, soapFault.faultstring, + null, "_requestSuccess", + request, null, + soapFault.detail, soapFault.faultactor + ); } - break; - } - }, - _fireEvent: function(eventName, eventData, cancelable){ - var listeners = this.listeners[eventName]; - if (!listeners) { - Xmla.Exception._newError( - "UNKNOWN_EVENT", - "Xmla._fireEvent", - eventName - )._throw(); - } - var n = listeners.length, outcome = true; - if (n) { - var listener, listenerResult, i; - for (i = 0; i < n; i++){ - listener = listeners[i]; - listenerResult = listener.handler.call( - listener.scope, - eventName, - eventData, - this - ); - if (cancelable && listenerResult===false){ - outcome = false; - break; + else { + switch(method){ + case Xmla.METHOD_DISCOVER: + request.rowset = response = new Xmla.Rowset(responseXml, request.requestType, this); + break; + case Xmla.METHOD_EXECUTE: + var resultset = null, dataset = null; + var format = request.properties[Xmla.PROP_FORMAT]; + switch(format){ + case Xmla.PROP_FORMAT_TABULAR: + response = resultset = new Xmla.Rowset(responseXml, null, this); + break; + case Xmla.PROP_FORMAT_MULTIDIMENSIONAL: + response = dataset = new Xmla.Dataset(responseXml); + break; + } + request.resultset = resultset; + request.dataset = dataset; + break; + } + this.response = response; } } - } - else //if there is neither a listener nor an error nor a general callback we explicitly throw the exception. - if (eventName === Xmla.EVENT_ERROR && !_isFun(eventData.error) && !_isFun(eventData.callback)) eventData.exception._throw(); - return outcome; - }, -/** -* Create a XML/A SOAP message that may be used as message body for a XML/A request -* @method getXmlaSoapMessage -* @param {object} options An object representing the message. The object can have these properties: -* @return {string} The SOAP message. -**/ - getXmlaSoapMessage: function getXmlaSoapMessage(options){ - var method = options.method, - msg = "" + - "\n<" + _xmlnsSOAPenvelopePrefix + ":Envelope" + - " " + _xmlnsIsSOAPenvelope + - " " + _SOAPencodingStyle + ">" + - "\n <" + _xmlnsSOAPenvelopePrefix + ":Body>" + - "\n <" + method + " " + _xmlnsIsXmla + " " + _SOAPencodingStyle + ">" - ; - switch(method){ - case Xmla.METHOD_DISCOVER: - if (!options.requestType) { - Xmla.Exception._newError( - "MISSING_REQUEST_TYPE", - "Xmla._getXmlaSoapMessage", - options - )._throw(); + catch (exception) { + request.exception = exception; + } + if (request.exception) { + switch(method){ + case Xmla.METHOD_DISCOVER: + this._fireEvent(Xmla.EVENT_DISCOVER_ERROR, request); + break; + case Xmla.METHOD_EXECUTE: + this._fireEvent(Xmla.EVENT_EXECUTE_ERROR, request); + break; } - msg += "\n <" + _xmlRequestType + ">" + options.requestType + "" + - _getXmlaSoapList("Restrictions", "RestrictionList", options.restrictions, " ") + - _getXmlaSoapList("Properties", "PropertyList", options.properties, " "); - break; - case Xmla.METHOD_EXECUTE: - if (!options.statement){ - Xmla.Exception._newError( - "MISSING_REQUEST_TYPE", - "Xmla._getXmlaSoapMessage", - options - )._throw(); + if (request.error) { + request.error.call(request.scope ? request.scope : null, this, request, request.exception); } - msg += "\n " + - "\n " + _xmlEncode(options.statement) + "" + - "\n " + - _getXmlaSoapList("Properties", "PropertyList", options.properties, " ") - ; - break; - default: - //we used to throw an exception here, - //but this would make it impossible - //to execute service or provider specific methods. - } - msg += "\n " + - "\n " + - "\n" - ; - return msg; - }, -/** -* Sends a request to the XML/A server. -* This method is rather low-level and allows full control over the request -* by passing an options object. General properties of the options object are: -* -* Other parts of the options object are method-specific. -* -* Instead of calling this method directly, consider calling -* discover() (to obtain a schema rowset), -* execute() (to issue a MDX query), -* or one of the specialized discoverXXX() methods (to obtain a particular schema rowset). -* @method request -* @param {Object} options An object whose properties convey the options for the request. -* @return {Xmla.Rowset|Xmla.Dataset} The result of the invoking the XML/A method. For an asynchronous request, the return value is not defined. For synchronous requests, Discover requests return an instance of a Xmla.Rowset, and Execute results return an instance of a Xmla.Dataset. -*/ - request: function(options){ - var ex, xmla = this; - - this.response = null; - this.responseText = null; - this.responseXML = null; - - options = _applyProps(options, this.options, false); - if (!options.url){ - ex = Xmla.Exception._newError( - "MISSING_URL", - "Xmla.request", - options - ); - ex._throw(); - } - options.properties = _applyProps(options.properties, this.options.properties, false); - options.restrictions = _applyProps(options.restrictions, this.options.restrictions, false); - delete options.exception; - - if ( - !this._fireEvent(Xmla.EVENT_REQUEST, options, true) || - (options.method == Xmla.METHOD_DISCOVER && !this._fireEvent(Xmla.EVENT_DISCOVER, options)) || - (options.method == Xmla.METHOD_EXECUTE && !this._fireEvent(Xmla.EVENT_EXECUTE, options)) - ){ - return false; - } - - var soapMessage = this.getXmlaSoapMessage(options); - this.soapMessage = soapMessage; - var myXhr; - var ajaxOptions = { - async: options.async, - timeout: options.requestTimeout, - data: soapMessage, - error: function(exception){ - options.exception = exception; - xmla._requestError(options, exception); - }, - complete: function(xhr){ - options.xhr = xhr; - xmla._requestSuccess(options); - }, - url: options.url - }; - if (options.username) { - ajaxOptions.username = options.username; - } - if (options.password) { - ajaxOptions.password = options.password; - } - - var headers = {}; - if (this.options.headers) { - headers = _applyProps(headers, this.options.headers); - } - if (options.headers) { - headers = _applyProps(headers, options.headers, true); - } - ajaxOptions.headers = headers; - - myXhr = _ajax(ajaxOptions); - return this.response; - }, - _requestError: function(options, exception) { - if (options.error) { - options.error.call(options.scope ? options.scope : null, this, options, exception); - } - if (options.callback) { - options.callback.call(options.scope ? options.scope : null, Xmla.EVENT_ERROR, this, options, exception); - } - this._fireEvent(Xmla.EVENT_ERROR, options); - }, - //https://msdn.microsoft.com/en-us/library/ms187142.aspx#handling_soap_faults - _parseSoapFault: function(soapFault){ - //Get faultactor, faultstring, faultcode and detail elements - function _parseSoapFaultDetail(detailNode){ - var errors = []; - var i, childNodes = detailNode.childNodes, n = childNodes.length, childNode; - for (i = 0; i < n; i++) { - childNode = childNodes[i]; - if (childNode.nodeType !== 1) { - continue; - } - switch (childNode.nodeName){ - case "Error": - errors.push({ - ErrorCode: _getAttribute(childNode, "ErrorCode"), - Description: _getAttribute(childNode, "Description"), - Source: _getAttribute(childNode, "Source"), - HelpFile: _getAttribute(childNode, "HelpFile") - }); - break; - default: - } - } - return errors; - } - - var fields = {}, field, nodeName; - var i, childNodes = soapFault.childNodes, n = childNodes.length, childNode; - for (i = 0; i < n; i++){ - childNode = childNodes[i]; - if (childNode.nodeType !== 1) { - continue; - } - nodeName = childNode.nodeName; - switch (nodeName) { - case "faultactor": - case "faultstring": - case "faultcode": - field = _getElementText(childNode); - break; - case "detail": - field = _parseSoapFaultDetail(childNode); - break; - default: - field = null; - break; - } - if (field) { - fields[nodeName] = field; - } - } - return fields; - }, - _requestSuccess: function(request) { - var xhr = request.xhr, response; - if (request.forceResponseXMLEmulation !== true) { - this.responseXML = xhr.responseXML; - } - this.responseText = xhr.responseText; - - var method = request.method; - - try { - var responseXml = this.getResponseXML(); - if (!responseXml) { - request.exception = new Xmla.Exception( - Xmla.Exception.TYPE_ERROR, - Xmla.Exception.ERROR_PARSING_RESPONSE_CDE, - "Response is not an XML document." - ); - } - var soapFault = _getElementsByTagNameNS(responseXml, _xmlnsSOAPenvelope, _xmlnsSOAPenvelopePrefix, "Fault"); - if (soapFault.length) { - //TODO: extract error info - soapFault = soapFault[0]; - soapFault = this._parseSoapFault(soapFault); - //type, code, message, helpfile, source, data, args, detail, actor - request.exception = new Xmla.Exception( - Xmla.Exception.TYPE_ERROR, - soapFault.faultcode, soapFault.faultstring, - null, "_requestSuccess", - request, null, - soapFault.detail, soapFault.faultactor - ); + if (request.callback) { + request.callback.call(request.scope ? request.scope : null, Xmla.EVENT_ERROR, this, request, request.exception); + } + this._fireEvent(Xmla.EVENT_ERROR, request); } else { switch(method){ case Xmla.METHOD_DISCOVER: - request.rowset = response = new Xmla.Rowset(responseXml, request.requestType, this); + this._fireEvent(Xmla.EVENT_DISCOVER_SUCCESS, request); break; case Xmla.METHOD_EXECUTE: - var resultset = null, dataset = null; - var format = request.properties[Xmla.PROP_FORMAT]; - switch(format){ - case Xmla.PROP_FORMAT_TABULAR: - response = resultset = new Xmla.Rowset(responseXml, null, this); - break; - case Xmla.PROP_FORMAT_MULTIDIMENSIONAL: - response = dataset = new Xmla.Dataset(responseXml); - break; - } - request.resultset = resultset; - request.dataset = dataset; + this._fireEvent(Xmla.EVENT_EXECUTE_SUCCESS, request); break; } - this.response = response; + if (request.success) { + request.success.call( + request.scope ? request.scope : null, + this, request, response + ); + } + if (request.callback) { + request.callback.call( + request.scope ? request.scope : null, + Xmla.EVENT_SUCCESS, this, request, response + ); + } + this._fireEvent(Xmla.EVENT_SUCCESS, request); } - } - catch (exception) { - request.exception = exception; - } - if (request.exception) { - switch(method){ - case Xmla.METHOD_DISCOVER: - this._fireEvent(Xmla.EVENT_DISCOVER_ERROR, request); - break; - case Xmla.METHOD_EXECUTE: - this._fireEvent(Xmla.EVENT_EXECUTE_ERROR, request); - break; + }, + /** + * Sends an MDX query to a XML/A DataSource to invoke the XML/A Execute method and obtain the multi-dimensional resultset. + * Options are passed using a generic options object. + * Applicable properties of the options object are: + * + * @method execute + * @param {Object} options An object whose properties convey the options for the XML/A Execute request. + * @return {Xmla.Dataset|Xmla.Rowset} The result of the invoking the XML/A Execute method. For an asynchronous request, the return value is not defined. For synchronous requests, an instance of a Xmla.Dataset that represents the multi-dimensional result set of the MDX query. If the Format property in the request was set to Tabular, then an instance of the + Rowset class is returned to represent the Resultset. + */ + execute: function(options) { + var properties = options.properties; + if (!properties){ + properties = {}; + options.properties = properties; } - if (request.error) { - request.error.call(request.scope ? request.scope : null, this, request, request.exception); + _applyProps(properties, this.options.properties, false) + if (!properties[Xmla.PROP_CONTENT]) { + properties[Xmla.PROP_CONTENT] = Xmla.PROP_CONTENT_SCHEMADATA; } - if (request.callback) { - request.callback.call(request.scope ? request.scope : null, Xmla.EVENT_ERROR, this, request, request.exception); + if (!properties[Xmla.PROP_FORMAT]) { + options.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_MULTIDIMENSIONAL; } - this._fireEvent(Xmla.EVENT_ERROR, request); - } - else { - switch(method){ - case Xmla.METHOD_DISCOVER: - this._fireEvent(Xmla.EVENT_DISCOVER_SUCCESS, request); - break; - case Xmla.METHOD_EXECUTE: - this._fireEvent(Xmla.EVENT_EXECUTE_SUCCESS, request); - break; + var request = _applyProps(options, { + method: Xmla.METHOD_EXECUTE + }, true); + return this.request(request); + }, + /** + * Sends an MDX query to a XML/A DataSource to invoke the execute() method using PROP_FORMAT_TABULAR as value for the PROP_FORMAT property. This has the effect of obtaining the multi-dimensional resultset as a Rowset. + * @method executeTabular + * @param {Object} options An object whose properties convey the options for the XML/A Execute request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Execute method. For an asynchronous request, the return value is not defined. For synchronous requests, an instance of a Xmla.Rowset that represents the multi-dimensional result set of the MDX query. + */ + executeTabular: function(options){ + if (!options.properties) { + options.properties = {}; + } + options.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_TABULAR; + return this.execute(options); + }, + /** + * Sends an MDX query to a XML/A DataSource to invoke the PROP_FORMAT_MULTIDIMENSIONAL as value for the PROP_FORMAT property. In this case, the result is available only as XML text or XML document in the responseText + and responseXML properties. + * @method executeMultiDimensional + * @param {Object} options An object whose properties convey the options for the XML/A Execute request. + */ + executeMultiDimensional: function(options){ + if (!options.properties) { + options.properties = {}; } - if (request.success) { - request.success.call( - request.scope ? request.scope : null, - this, request, response - ); + options.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_MULTIDIMENSIONAL; + return this.execute(options); + }, + /** + * Sends a request to invoke the XML/A Discover method and returns a schema rowset specified by the requestType option. + * Options are passed using a generic options object. + * Applicable properties of the options object are: + * + * Instead of calling this method directly, consider calling + * or one of the specialized discoverXXX() methods to obtain a particular schema rowset. + * @method discover + * @param {Object} options An object whose properties convey the options for the XML/A Discover request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the requested schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discover: function(options) { + var request = _applyProps(options, { + method: Xmla.METHOD_DISCOVER + }, true); + if (!request.requestType) { + request.requestType = this.options.requestType; } - if (request.callback) { - request.callback.call( - request.scope ? request.scope : null, - Xmla.EVENT_SUCCESS, this, request, response - ); + if (!request.properties) { + request.properties = {}; } - this._fireEvent(Xmla.EVENT_SUCCESS, request); - } - }, -/** -* Sends an MDX query to a XML/A DataSource to invoke the XML/A Execute method and obtain the multi-dimensional resultset. -* Options are passed using a generic options object. -* Applicable properties of the options object are: -* -* @method execute -* @param {Object} options An object whose properties convey the options for the XML/A Execute request. -* @return {Xmla.Dataset|Xmla.Rowset} The result of the invoking the XML/A Execute method. For an asynchronous request, the return value is not defined. For synchronous requests, an instance of a Xmla.Dataset that represents the multi-dimensional result set of the MDX query. If the Format property in the request was set to Tabular, then an instance of the -Rowset class is returned to represent the Resultset. -*/ - execute: function(options) { - var properties = options.properties; - if (!properties){ - properties = {}; - options.properties = properties; - } - _applyProps(properties, this.options.properties, false) - if (!properties[Xmla.PROP_CONTENT]) { - properties[Xmla.PROP_CONTENT] = Xmla.PROP_CONTENT_SCHEMADATA; - } - if (!properties[Xmla.PROP_FORMAT]) { - options.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_MULTIDIMENSIONAL; - } - var request = _applyProps(options, { - method: Xmla.METHOD_EXECUTE - }, true); - return this.request(request); - }, -/** -* Sends an MDX query to a XML/A DataSource to invoke the execute() method using PROP_FORMAT_TABULAR as value for the PROP_FORMAT property. This has the effect of obtaining the multi-dimensional resultset as a Rowset. -* @method executeTabular -* @param {Object} options An object whose properties convey the options for the XML/A Execute request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Execute method. For an asynchronous request, the return value is not defined. For synchronous requests, an instance of a Xmla.Rowset that represents the multi-dimensional result set of the MDX query. -*/ - executeTabular: function(options){ - if (!options.properties) { - options.properties = {}; - } - options.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_TABULAR; - return this.execute(options); - }, -/** -* Sends an MDX query to a XML/A DataSource to invoke the PROP_FORMAT_MULTIDIMENSIONAL as value for the PROP_FORMAT property. In this case, the result is available only as XML text or XML document in the responseText -and responseXML properties. -* @method executeMultiDimensional -* @param {Object} options An object whose properties convey the options for the XML/A Execute request. -*/ - executeMultiDimensional: function(options){ - if (!options.properties) { - options.properties = {}; - } - options.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_MULTIDIMENSIONAL; - return this.execute(options); - }, -/** -* Sends a request to invoke the XML/A Discover method and returns a schema rowset specified by the requestType option. -* Options are passed using a generic options object. -* Applicable properties of the options object are: -* -* Instead of calling this method directly, consider calling -* or one of the specialized discoverXXX() methods to obtain a particular schema rowset. -* @method discover -* @param {Object} options An object whose properties convey the options for the XML/A Discover request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the requested schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discover: function(options) { - var request = _applyProps(options, { - method: Xmla.METHOD_DISCOVER - }, true); - if (!request.requestType) { - request.requestType = this.options.requestType; + request.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_TABULAR; + return this.request(request); + }, + /** + * Invokes the discover() method using as value for the requestType, + * and retrieves the DISCOVER_DATASOURCES schema rowset. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
+ * DataSourceName + * + * string + * + * A name that identifies this data source. + * + * Yes + * + * No + *
+ * DataSourceDescription + * + * string + * + * Human readable description of the datasource + * + * No + * + * Yes + *
+ * URL + * + * string + * + * URL to use to submit requests to this provider. + * + * Yes + * + * Yes + *
+ * DataSourceInfo + * + * string + * + * Connectstring + * + * No + * + * Yes + *
+ * ProviderName + * + * string + * + * A name indicating the product providing the XML/A implementation + * + * Yes + * + * Yes + *
+ * ProviderType + * + * string[] + * + * The kind of data sets supported by this provider. + * The following values are defined by the XML/A specification: + *
+ *
TDP
tabular data provider.
+ *
MDP
multidimensiona data provider.
+ *
DMP
data mining provider.
+ *
+ * Note: multiple values are possible. + *
+ * Yes + * + * No + *
+ * AuthenticationMode + * + * string + * + * Type of security offered by the provider + * The following values are defined by the XML/A specification: + *
+ *
Unauthenticated
no user ID or password needs to be sent.
+ *
Authenticated
User ID and password must be included in the information required for the connection.
+ *
Integrated
the data source uses the underlying security to determine authorization
+ *
+ *
+ * Yes + * + * No + *
+ * + * @method discoverDataSources + * @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_DATASOURCES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_DATASOURCES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDataSources: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DISCOVER_DATASOURCES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using as value for the requestType, + * and retrieves the DISCOVER_PROPERTIES schema rowset. + * This rowset provides information on the properties that are supported by the XML/A provider. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
+ * PropertyName + * + * string + * + * The name of the property + * + * Yes (array) + * + * No + *
+ * PropertyDescription + * + * string + * + * Human readable description of the property + * + * No + * + * Yes + *
+ * PropertyType + * + * string + * + * The property's datatype (as an XML Schema data type) + * + * No + * + * Yes + *
+ * PropertyAccessType + * + * string + * + * How the property may be accessed. Values defined by the XML/A spec are: + *
    + *
  • Read
  • + *
  • Write
  • + *
  • ReadWrite
  • + *
+ *
+ * No + * + * No + *
+ * IsRequired + * + * boolean + * + * true if the property is required, false if not. + * + * No + * + * Yes + *
+ * Value + * + * string + * + * The property's current value. + * + * No + * + * Yes + *
+ * + * @method discoverProperties + * @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_DATASOURCES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_DATASOURCES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverProperties: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DISCOVER_PROPERTIES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using as value for the requestType, + * and retrieves the DISCOVER_SCHEMA_ROWSETS schema rowset. + * This rowset lists all possible request types supported by this provider. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
SchemaNamestringThe requestType. YesNo
RestrictionsarrayA list of columns that may be used to filter the schema rowset.NoYes
DescriptionstringA human readable description of the schema rowset that is returned when using this requestTypeNoYes
+ * + * @method discoverSchemaRowsets + * @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_SCHEMA_ROWSETS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_DATASOURCES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverSchemaRowsets: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DISCOVER_SCHEMA_ROWSETS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using as value for the requestType, + * and retrieves the DISCOVER_ENUMERATORS schema rowset. + * This rowset lists the names, data types, and enumeration values of enumerators supported by the XMLA Provider for a specific data source. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
EnumNamestringName of the enumerator. Yes (array)No
EnumDescriptionstringA human readable description of the enumeratorNoYes
EnumTypestringThe XML Schema data type of this enumeratorNoNo
ElementNamestringThe name of the enumerator entryNoNo
ElementDescriptionstringA human readable description of this enumerator entryNoYes
ElementValuestringThe value of this enumerator entryNoYes
+ * + * @method discoverEnumerators + * @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_ENUMERATORS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_ENUMERATORS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverEnumerators: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DISCOVER_ENUMERATORS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using as value for the requestType, + * and retrieves the DISCOVER_KEYWORDS schema rowset. + * This rowset is a list of reserved words for this XML/A provider. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
KeywordstringName of the enumerator. Yes (array)No
+ * + * @method discoverKeywords + * @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_KEYWORDS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_ENUMERATORS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverKeywords: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DISCOVER_KEYWORDS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using as value for the requestType, + * and retrieves the DISCOVER_LITERALS schema rowset. + * This rowset is a list of reserved words for this XML/A provider. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
LiteralNamestringName of the literal. Yes (array)No
LiteralValuestringThe actual literal value. NoYes
LiteralInvalidCharsstringCharacters that may not appear in the literal NoYes
LiteralInvalidStartingCharsstringCharacters that may not appear as first character in the literal NoYes
LiteralMaxLengthintmaximum number of characters for this literal, or -1 in case there is no maximum, or the maximum is unknownNoYes
+ * + * @method discoverLiterals + * @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_LITERALS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_LITERALS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverLiterals: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DISCOVER_LITERALS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the DBSCHEMA_CATALOGS schema rowset. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
DESCRIPTIONstringHuman readable descriptionNoYes
ROLESstringA comma-separatd list of roles available to the current user.NoYes
DATE_MODIFIEDDateThe date this catalog was modifiedNoYes
+ * @method discoverDBCatalogs + * @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_CATALOGS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_CATALOGS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDBCatalogs: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DBSCHEMA_CATALOGS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the DBSCHEMA_COLUMNS schema rowset. + * Provides column information for all columns meeting the provided restriction criteria. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
TABLE_CATALOGstringThe name of the Database.YesNo
TABLE_SCHEMAstringNot supported.YesNo
TABLE_NAMEstringThe name of the cube.YesNo
COLUMN_NAMEstringThe name of the attribute hierarchy or measure.YesNo
COLUMN_GUIDstringNot supported.NoNo
COLUMN_PROPIDintNot supported.NoNo
ORDINAL_POSITIONintThe position of the column, beginning with 1.NoNo
COLUMN_HAS_DEFAULTbooleanNot supported.NoNo
COLUMN_DEFAULTstringNot supported.NoNo
COLUMN_FLAGSintA DBCOLUMNFLAGS bitmask indicating column properties. See 'DBCOLUMNFLAGS Enumerated Type' in IColumnsInfo::GetColumnInfoNoNo
IS_NULLABLEbooleanAlways returns false.NoNo
DATA_TYPEstringThe data type of the column. Returns a string for dimension columns and a variant for measures.NoNo
TYPE_GUID + * srringNot supported.NoNo
CHARACTER_MAXIMUM_LENGTHintThe maximum possible length of a value within the column. This is retrieved from the DataSize property in the DataItem.NoNo
CHARACTER_OCTET_LENGTHintThe maximum possible length of a value within the column, in bytes, for character or binary columns. A value of zero (0) indicates the column has no maximum length. NULL will be returned for columns that do not return binary or character data types.NoNo
NUMERIC_PRECISIONintThe maximum precision of the column for numeric data types other than DBTYPE_VARNUMERIC.NoNo
NUMERIC_SCALEintThe number of digits to the right of the decimal point for DBTYPE_DECIMAL, DBTYPE_NUMERIC, DBTYPE_VARNUMERIC. Otherwise, this is NULL.NoNo
DATETIME_PRECISIONintNot supported.NoNo
CHARACTER_SET_CATALOGstringNot supported.NoNo
CHARACTER_SET_SCHEMAstringNot supported.NoNo
CHARACTER_SET_NAMEstringNot supported.NoNo
COLLATION_CATALOGstringNot supported.NoNo
COLLATION_SCHEMAstringNot supported.NoNo
COLLATION_NAMEstringNot supported.NoNo
DOMAIN_CATALOGstringNot supported.NoNo
DOMAIN_SCHEMAstringNot supported.NoNo
DOMAIN_NAMEstringNot supported.NoNo
DESCRIPTIONstringNot supported.NoNo
COLUMN_OLAP_TYPEstringThe OLAP type of the object. MEASURE indicates the object is a measure. ATTRIBUTE indicates the object is a dimension attribute.YesNo
+ * The rowset is sorted on TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME. + * @method discoverDBColumns + * @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_COLUMNS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_COLUMNS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDBColumns: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DBSCHEMA_COLUMNS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the DBSCHEMA_PROVIDER_TYPES schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
TYPE_NAMEstringThe provider-specific data type name.falsetrue
DATA_TYPEintThe indicator of the data type.falsetrue
COLUMN_SIZEint The length of a non-numeric column or parameter that refers to either the maximum or the length defined for this type by the provider. For character data, this is the maximum or defined length in characters. For DateTime data types, this is the length of the string representation (assuming the maximum allowed precision of the fractional seconds component). If the data type is numeric, this is the upper bound on the maximum precision of the data type. falsetrue
LITERAL_PREFIXstringThe character or characters used to prefix a literal of this type in a text command.falsetrue
LITERAL_SUFFIXstringThe character or characters used to suffix a literal of this type in a text command.falsetrue
CREATE_PARAMS + * stringThe creation parameters specified by the consumer when creating a column of this data type. For example, the SQL data type, DECIMAL, needs a precision and a scale. In this case, the creation parameters might be the string "precision,scale". In a text command to create a DECIMAL column with a precision of 10 and a scale of 2, the value of the TYPE_NAME column might be DECIMAL() and the complete type specification would be DECIMAL(10,2). The creation parameters appear as a comma-separated list of values, in the order they are to be supplied and with no surrounding parentheses. If a creation parameter is length, maximum length, precision, scale, seed, or increment, use "length", "max length", "precision", "scale", "seed", and "increment", respectively. If the creation parameter is some other value, the provider determines what text is to be used to describe the creation parameter. If the data type requires creation parameters, "()" usually appears in the type name. This indicates the position at which to insert the creation parameters. If the type name does not include "()", the creation parameters are enclosed in parentheses and appended to the data type name. falsetrue
IS_NULLABLEbooleanA Boolean that indicates whether the data type is nullable. VARIANT_TRUE indicates that the data type is nullable. VARIANT_FALSE indicates that the data type is not nullable. NULL indicates that it is not known whether the data type is nullable.falsetrue
CASE_SENSITIVEbooleanA Boolean that indicates whether the data type is a characters type and case-sensitive. VARIANT_TRUE indicates that the data type is a character type and is case-sensitive. VARIANT_FALSE indicates that the data type is not a character type or is not case-sensitive.falsetrue
SEARCHABLEintAn integer indicating how the data type can be used in searches if the provider supports ICommandText; otherwise, NULL. This column can have the following values: DB_UNSEARCHABLE indicates that the data type cannot be used in a WHERE clause. DB_LIKE_ONLY indicates that the data type can be used in a WHERE clause only with the LIKE predicate.DB_ALL_EXCEPT_LIKE indicates that the data type can be used in a WHERE clause with all comparison operators except LIKE. DB_SEARCHABLE indicates that the data type can be used in a WHERE clause with any comparison operator.falsetrue
UNSIGNED_ATTRIBUTEbooleanA Boolean that indicates whether the data type is unsigned. VARIANT_TRUE indicates that the data type is unsigned. VARIANT_FALSE indicates that the data type is signed.NULL indicates that this is not applicable to the data type.falsetrue
FIXED_PREC_SCALEbooleanA Boolean that indicates whether the data type has a fixed precision and scale. VARIANT_TRUE indicates that the data type has a fixed precision and scale. VARIANT_FALSE indicates that the data type does not have a fixed precision and scale.falsetrue
AUTO_UNIQUE_VALUEbooleanA Boolean that indicates whether the data type is autoincrementing. VARIANT_TRUE indicates that values of this type can be autoincrementing. VARIANT_FALSE indicates that values of this type cannot be autoincrementing. If this value is VARIANT_TRUE, whether or not a column of this type is always autoincrementing depends on the provider's DBPROP_COL_AUTOINCREMENT column property. If the DBPROP_COL_AUTOINCREMENT property is read/write, whether or not a column of this type is autoincrementing depends on the setting of the DBPROP_COL_AUTOINCREMENT property. If DBPROP_COL_AUTOINCREMENT is a read-only property, either all or none of the columns of this type are autoincrementing. falsetrue
LOCAL_TYPE_NAMEstringThe localized version of TYPE_NAME. NULL is returned if a localized name is not supported by the data provider.falsetrue
MINIMUM_SCALEintIf the type indicator is DBTYPE_VARNUMERIC, DBTYPE_DECIMAL, or DBTYPE_NUMERIC, the minimum number of digits allowed to the right of the decimal point. Otherwise, NULL.falsetrue
MAXIMUM_SCALEintThe maximum number of digits allowed to the right of the decimal point if the type indicator is DBTYPE_VARNUMERIC, DBTYPE_DECIMAL, or DBTYPE_NUMERIC; otherwise, NULL.falsetrue
GUIDstring(Intended for future use) The GUID of the type, if the type is described in a type library. Otherwise, NULL.falsetrue
TYPELIB + * string(Intended for future use) The type library containing the description of the type, if the type is described in a type library. Otherwise, NULL.falsetrue
VERSIONstring(Intended for future use) The version of the type definition. Providers might want to version type definitions. Different providers might use different versioning schemes, such as a timestamp or number (integer or float). NULL if not supported.falsetrue
IS_LONGbooleanA Boolean that indicates whether the data type is a binary large object (BLOB) and has very long data. VARIANT_TRUE indicates that the data type is a BLOB that contains very long data; the definition of very long data is provider-specific. VARIANT_FALSE indicates that the data type is a BLOB that does not contain very long data or is not a BLOB. This value determines the setting of the DBCOLUMNFLAGS_ISLONG flag returned by GetColumnInfo in IColumnsInfo and GetParameterInfo in ICommandWithParameters.falsetrue
BEST_MATCHbooleanA Boolean that indicates whether the data type is a best match. VARIANT_TRUE indicates that the data type is the best match between all data types in the data store and the OLE DB data type indicated by the value in the DATA_TYPE column. VARIANT_FALSE indicates that the data type is not the best match. For each set of rows in which the value of the DATA_TYPE column is the same, the BEST_MATCH column is set to VARIANT_TRUE in only one row.falsetrue
IS_FIXEDLENGTHbooleanA Boolean that indicates whether the column is fixed in length. VARIANT_TRUE indicates that columns of this type created by the data definition language (DDL) will be of fixed length. VARIANT_FALSE indicates that columns of this type created by the DDL will be of variable length. If the field is NULL, it is not known whether the provider will map this field with a fixed-length or variable-length column. + * falsetrue
+ * @method discoverDBProviderTypes + * @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_PROVIDER_TYPES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_PROVIDER_TYPES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDBProviderTypes: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DBSCHEMA_PROVIDER_TYPES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the DBSCHEMA_SCHEMATA schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
+ * @method discoverDBSchemata + * @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_SCHEMATA request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_SCHEMATA schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDBSchemata: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DBSCHEMA_SCHEMATA + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the DBSCHEMA_TABLES schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
+ * @method discoverDBTables + * @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_TABLES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_TABLES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDBTables: function(options){ + var request = _applyProps(options, { + requestType: Xmla.DBSCHEMA_TABLES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the DBSCHEMA_TABLES_INFO schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
+ * @method discoverDBTablesInfo + * @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_TABLES_INFO request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_TABLES_INFO schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverDBTablesInfo: function(options){ + var request = _applyProps( + options, + { + requestType: Xmla.DBSCHEMA_TABLES_INFO + }, + true + ); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_ACTIONS schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
+ * @method discoverMDActions + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_ACTIONS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_ACTIONS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDActions: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_ACTIONS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_CUBES schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
CUBE_TYPEstringType of the cube.NoNo
CUBE_GUIDstringNot supportedNoNo
CREATED_ONDateNot supportedNoNo
LAST_SCHEMA_UPDATEDateThe time that the cube was last processed.NoNo
SCHEMA_UPDATED_BYstringNoNo
LAST_DATA_UPDATEDateThe time that the cube was last processed.NoNo
DATA_UPDATED_BYstringNoNo
DESCRIPTIONstringA Human-readable description of the cube.NoNo
IS_DRILLTHROUGH_ENABLEDbooleanNoNo
IS_LINKABLEbooleanNoNo
IS_WRITE_ENABLEDbooleanNoNo
IS_SQL_ENABLEDbooleanNoNo
CUBE_CAPTIONstringCaption for this cube.NoNo
BASE_CUBE_NAMEstringName of the source cube (if this cube is a perspective cube).YesNo
ANNOTATIONSstringNotes in xml formatNoNo
+ * @method discoverMDCubes + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_CUBES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_CUBES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDCubes: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_CUBES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_DIMENSIONS schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
DIMENSION_NAMEstringName of the dimension.YesNo
DIMENSION_UNIQUE_NAMEstringUnique name for this dimension.YesNo
DIMENSION_GUIDstringNoYes
DIMENSION_CAPTIONstringNoYes
DIMENSION_ORDINALintNoYes
DIMENSION_TYPEstring + *
    + *
  • MD_DIMTYPE_UNKNOWN (0)
  • + *
  • MD_DIMTYPE_TIME (1)
  • + *
  • MD_DIMTYPE_MEASURE (2)
  • + *
  • MD_DIMTYPE_OTHER (3)
  • + *
  • MD_DIMTYPE_QUANTITATIVE (5)
  • + *
  • MD_DIMTYPE_ACCOUNTS (6)
  • + *
  • MD_DIMTYPE_CUSTOMERS (7)
  • + *
  • MD_DIMTYPE_PRODUCTS (8)
  • + *
  • MD_DIMTYPE_SCENARIO (9)
  • + *
  • MD_DIMTYPE_UTILIY (10)
  • + *
  • MD_DIMTYPE_CURRENCY (11)
  • + *
  • MD_DIMTYPE_RATES (12)
  • + *
  • MD_DIMTYPE_CHANNEL (13)
  • + *
  • MD_DIMTYPE_PROMOTION (14)
  • + *
  • MD_DIMTYPE_ORGANIZATION (15)
  • + *
  • MD_DIMTYPE_BILL_OF_MATERIALS (16)
  • + *
  • MD_DIMTYPE_GEOGRAPHY (17)
  • + *
+ *
NoYes
DIMENSION_CARDINALITYintNoYes
DEFAULT_HIERARCHYstringNoYes
DESCRIPTIONstringA Human-readable description of the dimension.NoNo
IS_VIRTUALbooleanNoNo
IS_READWRITEbooleanNoNo
DIMENSION_UNIQUE_SETTINGSNoNo
DIMENSION_MASTER_UNIQUE_NAMENoNo
DIMENSION_IS_VISIBLEbooleanNoNo
+ * @method discoverMDDimensions + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_DIMENSIONS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_DIMENSIONS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDDimensions: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_DIMENSIONS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_FUNCTIONS schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
FUNCTION_NAMEDBTYPE_WSTRThe name of the function.YesYes
DESCRIPTIONDBTYPE_WSTRA description of the function.NoNo
PARAMETER_LISTDBTYPE_WSTRA comma delimited list of parameters formatted as in Microsoft Visual Basic. For example, a parameter might be Name as String.NoNo
RETURN_TYPEDBTYPE_I4The VARTYPE of the return data type of the function.NoNo
ORIGINDBTYPE_I4The origin of the function: + *
    + *
  1. for MDX functions.
  2. + *
  3. for user-defined functions.
  4. + *
+ *
YesYes
INTERFACE_NAMEDBTYPE_WSTRThe name of the interface for user-defined functions. The group name for Multidimensional Expressions (MDX) functions.YesYes
LIBRARY_NAMEDBTYPE_WSTRThe name of the type library for user-defined functions. NULL for MDX functions.YesYes
DLL_NAMEDBTYPE_WSTR(Optional) The name of the assembly that implements the user-defined function. Returns VT_NULL for MDX functions.NoNo
HELP_FILEDBTYPE_WSTR(Optional) The name of the file that contains the help documentation for the user-defined function.Returns VT_NULL for MDX functions.NoNo
HELP_CONTEXTDBTYPE_I4(Optional) Returns the Help context ID for this function.NoNo
OBJECTDBTYPE_WSTR + * (Optional) The generic name of the object class to which a property applies. For example, the rowset corresponding to the .Members function returns "Level". + * Returns VT_NULL for user-defined functions, or non-property MDX functions. + * NoNo
CAPTIONDBTYPE_WSTRThe display caption for the function.NoNo
+ * @method discoverMDFunctions + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_FUNCTIONS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_FUNCTIONS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDFunctions: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_FUNCTIONS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_HIERARCHIES schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
DIMENSION_UNIQUE_NAMEstringUnique name for this dimension.YesNo
HIERARCHY_NAMEstringName of the hierarchy.YesNo
HIERARCHY_UNIQUE_NAMEstringUnique name for this hierarchy.YesNo
HIERARCHY_GUIDstringNoYes
HIERARCHY_CAPTIONstringNoYes
DIMENSION_TYPEstringNoYes
HIERARCHY_CARDINALITYintNoYes
DEFAULT_MEMBERstringNoYes
ALL_MEMBERstringNoYes
DESCRIPTIONstringA Human-readable description of the dimension.NoNo
STRUCTUREstringNoYes
IS_VIRTUALbooleanNoYes
IS_READWRITEbooleanNoYes
DIMENSION_UNIQUE_SETTINGSstringNoYes
DIMENSION_MASTER_UNIQUE_NAMEstringNoYes
DIMENSION_IS_VISIBLEbooleanNoYes
HIERARCHY_ORDINALintNoYes
DIMENSION_IS_SHAREDbooleanNoYes
HIERARCHY_IS_VISIBLEbooleanNoYes
HIERARCHY_ORIGINYesYes
HIERARCHY_DISPLAY_FOLDERstringNoYes
INSTANCE_SELECTIONstringNoYes
+ * @method discoverMDHierarchies + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_HIERARCHIES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_HIERARCHIES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDHierarchies: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_HIERARCHIES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_LEVELS schema rowset. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the catalog to which this level belongs. NULL if the provider does not support catalogs.YesYes
SCHEMA_NAMEstringThe name of the schema to which this level belongs. NULL if the provider does not support schemas.YesYes
CUBE_NAMEstringThe name of the cube to which this level belongs.YesYes
DIMENSION_UNIQUE_NAMEstringThe unique name of the dimension to which this level belongs. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
HIERARCHY_UNIQUE_NAMEstringThe unique name of the hierarchy. If the level belongs to more than one hierarchy, there is one row for each hierarchy to which it belongs. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
LEVEL_NAMEstringThe name of the level.YesYes
LEVEL_UNIQUE_NAMEstringThe properly escaped unique name of the level.YesYes
LEVEL_GUIDstringNot supported.NoYes
LEVEL_CAPTIONstringA label or caption associated with the hierarchy. Used primarily for display purposes. If a caption does not exist, LEVEL_NAME is returned.NoYes
LEVEL_NUMBERintThe distance of the level from the root of the hierarchy. Root level is zero (0).NoYes
LEVEL_CARDINALITYintThe number of members in the level.NoYes
LEVEL_TYPEintType of the level: + *
    + *
  • MDLEVEL_TYPE_REGULAR (0x0000)
  • + *
  • MDLEVEL_TYPE_ALL (0x0001)
  • + *
  • MDLEVEL_TYPE_TIME_YEARS (0x0014)
  • + *
  • MDLEVEL_TYPE_TIME_HALF_YEAR (0x0024)
  • + *
  • MDLEVEL_TYPE_TIME_QUARTERS (0x0044)
  • + *
  • MDLEVEL_TYPE_TIME_MONTHS (0x0084)
  • + *
  • MDLEVEL_TYPE_TIME_WEEKS (0x0104)
  • + *
  • MDLEVEL_TYPE_TIME_DAYS (0x0204)
  • + *
  • MDLEVEL_TYPE_TIME_HOURS (0x0304)
  • + *
  • MDLEVEL_TYPE_TIME_MINUTES (0x0404)
  • + *
  • MDLEVEL_TYPE_TIME_SECONDS (0x0804)
  • + *
  • MDLEVEL_TYPE_TIME_UNDEFINED (0x1004)
  • + *
  • MDLEVEL_TYPE_GEO_CONTINENT (0x2001)
  • + *
  • MDLEVEL_TYPE_GEO_REGION (0x2002)
  • + *
  • MDLEVEL_TYPE_GEO_COUNTRY (0x2003)
  • + *
  • MDLEVEL_TYPE_GEO_STATE_OR_PROVINCE (0x2004)
  • + *
  • MDLEVEL_TYPE_GEO_COUNTY (0x2005)
  • + *
  • MDLEVEL_TYPE_GEO_CITY (0x2006)
  • + *
  • MDLEVEL_TYPE_GEO_POSTALCODE (0x2007)
  • + *
  • MDLEVEL_TYPE_GEO_POINT (0x2008)
  • + *
  • MDLEVEL_TYPE_ORG_UNIT (0x1011)
  • + *
  • MDLEVEL_TYPE_BOM_RESOURCE (0x1012)
  • + *
  • MDLEVEL_TYPE_QUANTITATIVE (0x1013)
  • + *
  • MDLEVEL_TYPE_ACCOUNT (0x1014)
  • + *
  • MDLEVEL_TYPE_CUSTOMER (0x1021)
  • + *
  • MDLEVEL_TYPE_CUSTOMER_GROUP (0x1022)
  • + *
  • MDLEVEL_TYPE_CUSTOMER_HOUSEHOLD (0x1023)
  • + *
  • MDLEVEL_TYPE_PRODUCT (0x1031)
  • + *
  • MDLEVEL_TYPE_PRODUCT_GROUP (0x1032)
  • + *
  • MDLEVEL_TYPE_SCENARIO (0x1015)
  • + *
  • MDLEVEL_TYPE_UTILITY (0x1016)
  • + *
  • MDLEVEL_TYPE_PERSON (0x1041)
  • + *
  • MDLEVEL_TYPE_COMPANY (0x1042)
  • + *
  • MDLEVEL_TYPE_CURRENCY_SOURCE (0x1051)
  • + *
  • MDLEVEL_TYPE_CURRENCY_DESTINATION (0x1052)
  • + *
  • MDLEVEL_TYPE_CHANNEL (0x1061)
  • + *
  • MDLEVEL_TYPE_REPRESENTATIVE (0x1062)
  • + *
  • MDLEVEL_TYPE_PROMOTION (0x1071)
  • + *
+ * Some of the OLE DB for OLAP values are as flags, and do not become values of the enumeration: + *
    + *
  • MDLEVEL_TYPE_UNKNOWN (0x0000) signals that no other flags are set.
  • + *
  • MDLEVEL_TYPE_CALCULATED (0x0002) indicates that the level is calculated.
  • + *
  • MDLEVEL_TYPE_TIME (0x0004) indicates that the level is time-related.
  • + *
  • MDLEVEL_TYPE_RESERVED1 (0x0008) is reserved for future use.
  • + *
+ *
NoYes
DESCRIPTIONstringA human-readable description of the level. NULL if no description exists.NoYes
CUSTOM_ROLLUP_SETTINGSintA bitmap that specifies the custom rollup options: + *
    + *
  • MDLEVELS_CUSTOM_ROLLUP_EXPRESSION (0x01) indicates an expression exists for this level. (Deprecated)
  • + *
  • MDLEVELS_CUSTOM_ROLLUP_COLUMN (0x02) indicates that there is a custom rollup column for this level.
  • + *
  • MDLEVELS_SKIPPED_LEVELS (0x04) indicates that there is a skipped level associated with members of this level.
  • + *
  • MDLEVELS_CUSTOM_MEMBER_PROPERTIES (0x08) indicates that members of the level have custom member properties.
  • + *
  • MDLEVELS_UNARY_OPERATOR (0x10) indicates that members on the level have unary operators.
  • + *
+ *
NoYes
LEVEL_UNIQUE_SETTINGSintA bitmap that specifies which columns contain unique values, if the level only has members with unique names or keys. + * The Msmd.h file defines the following bit value constants for this bitmap: + *
    + *
  • MDDIMENSIONS_MEMBER_KEY_UNIQUE (1)
  • + *
  • MDDIMENSIONS_MEMBER_NAME_UNIQUE (2)
  • + *
+ * The key is always unique in Microsoft SQL Server 2005 Analysis Services (SSAS). + * The name will be unique if the setting on the attribute is UniqueInDimension or UniqueInAttribute + *
NoYes
LEVEL_IS_VISIBLEboolA Boolean that indicates whether the level is visible. Always returns True. If the level is not visible, it will not be included in the schema rowset.NoYes
LEVEL_ORDERING_PROPERTYstringThe ID of the attribute that the level is sorted on.NoYes
LEVEL_DBTYPEintThe DBTYPE enumeration of the member key column that is used for the level attribute. Null if concatenated keys are used as the member key column.NoYes
LEVEL_MASTER_UNIQUE_NAMEstringAlways returns NULL.NoYes
LEVEL_NAME_SQL_COLUMN_NAMEstringThe SQL representation of the level member names.NoYes
LEVEL_KEY_SQL_COLUMN_NAMEstringThe SQL representation of the level member key values.NoYes
LEVEL_UNIQUE_NAME_SQL_COLUMN_NAMEstringThe SQL representation of the member unique names.NoYes
LEVEL_ATTRIBUTE_HIERARCHY_NAMEstringThe name of the attribute hierarchy providing the source of the level.NoYes
LEVEL_KEY_CARDINALITYintThe number of columns in the level key.NoYes
LEVEL_ORIGINintA bit map that defines how the level was sourced:MD_ORIGIN_USER_DEFINED identifies levels in a user defined hierarchy.MD_ORIGIN_ATTRIBUTE identifies levels in an attribute hierarchy.MD_ORIGIN_KEY_ATTRIBUTE identifies levels in a key attribute hierarchy.MD_ORIGIN_INTERNAL identifies levels in attribute hierarchies that are not enabled.NoYes
+ * @method discoverMDLevels + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_LEVELS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_LEVELS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDLevels: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_LEVELS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_MEASURES schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
MEASURE_NAMEstringThe name of the measure.YesNo
MEASURE_UNIQUE_NAMEstringThe Unique name of the measure. For providers that generate unique names by qualification, each component of this name is delimited.YesNo
MEASURE_CAPTIONstringA label or caption associated with the measure. Used primarily for display purposes. If a caption does not exist, MEASURE_NAME is returned.NoNo
MEASURE_GUIDstringNot supported.NoNo
MEASURE_AGGREGATORintAn enumeration that indicates how the measure was derived. See http://msdn.microsoft.com/en-us/library/ms126250.aspxNoNo
DATA_TYPEintThe data type of the measure. Valid values are: + *
+ *
DBTYPE_EMPTY
0
+ *
DBTYPE_NULL
1
+ *
DBTYPE_I2
2
+ *
DBTYPE_I4
3
+ *
DBTYPE_R4
4
+ *
DBTYPE_R8
5
+ *
DBTYPE_CY
6
+ *
DBTYPE_DATE
7
+ *
DBTYPE_BSTR
8
+ *
DBTYPE_IDISPATCH
9
+ *
DBTYPE_ERROR
10
+ *
DBTYPE_BOOL
11
+ *
DBTYPE_VARIANT
12
+ *
DBTYPE_IUNKNOWN
13
+ *
DBTYPE_DECIMAL
14
+ *
DBTYPE_UI1
17
+ *
DBTYPE_ARRAY
0x2000
+ *
DBTYPE_BYREF
0x4000
+ *
DBTYPE_I1
16
+ *
DBTYPE_UI2
18
+ *
DBTYPE_UI4
19
+ *
DBTYPE_I8
20
+ *
DBTYPE_UI8
21
+ *
DBTYPE_GUID
72
+ *
DBTYPE_VECTOR
0x1000
+ *
DBTYPE_FILETIME
64
+ *
DBTYPE_RESERVED
0x8000
+ *
DBTYPE_BYTES
128
+ *
DBTYPE_STR
129
+ *
DBTYPE_WSTR
130
+ *
DBTYPE_NUMERIC
131
+ *
DBTYPE_UDT
132
+ *
DBTYPE_DBDATE
133
+ *
DBTYPE_DBTIME
134
+ *
DBTYPE_DBTIMESTAMP
135
+ *
DBTYPE_HCHAPTER
136
+ *
DBTYPE_PROPVARIANT
138
+ *
DBTYPE_VARNUMERIC
139
+ *
+ * See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms711251(v=vs.85).aspx
NoNo
NUMERIC_PRECISIONintThe maximum precision of the property if the measure object's data type is exact numeric. NULL for all other property types.NoNo
NUMERIC_SCALEintThe number of digits to the right of the decimal point if the measure object's type indicator is DBTYPE_NUMERIC or DBTYPE_DECIMAL. Otherwise, this value is NULL.NoNo
MEASURE_UNITSintNot supported.NoNo
DESCRIPTIONstringA human-readable description of the measure. NULL if no description exists.NoNo
EXPRESSIONstringAn expression for the member.NoNo
MEASURE_IS_VISIBLEbooleanA Boolean that always returns True. If the measure is not visible, it will not be included in the schema rowset.NoNo
LEVELS_LISTstringA string that always returns NULL.NoNo
MEASURE_NAME_SQL_COLUMN_NAMEstringThe name of the column in the SQL query that corresponds to the measure's name.NoNo
MEASURE_UNQUALIFIED_CAPTIONstringThe name of the measure, not qualified with the measure group name.NoNo
MEASUREGROUP_NAMEstringThe name of the measure group to which the measure belongs.YesNo
MEASURE_DISPLAY_FOLDERstringThe path to be used when displaying the measure in the user interface. Folder names will be separated by a semicolon. Nested folders are indicated by a backslash (\).NoNo
DEFAULT_FORMAT_STRINGstringThe default format string for the measure.NoNo
+ * @method discoverMDMeasures + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_MEASURES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_MEASURES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDMeasures: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_MEASURES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_MEMBERS schema rowset. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the catalogYesNo
SCHEMA_NAMEstringThe name of the schemaYesNo
CUBE_NAMEstringThe name of the cubeYesNo
DIMENSION_UNIQUE_NAMEstringThe unique name of the dimensionYesNo
HIERARCHY_UNIQUE_NAMEstringThe unique name of the hierarchyYesNo
LEVEL_UNIQUE_NAMEstringThe unique name of the levelYesNo
LEVEL_NUMBERintDistance of this level to the rootYesNo
MEMBER_ORDINALintDeprecated: always 0NoNo
MEMBER_NAMEstringThe name of this memberYesNo
MEMBER_UNIQUE_NAMEstringThe unique name of this memberYesNo
MEMBER_TYPEintAn integer constant indicating the type of this member. Can take on one of the following values: + * + * YesNo
MEMBER_GUIDstringThe guid of this memberNoNo
MEMBER_CAPTIONstringA label or caption associated with the member. Used primarily for display purposes. If a caption does not exist, MEMBER_NAME is returned.NoNo
CHILDREN_CARDINALITYintThe number of childrend for this memberNoNo
PARENT_LEVELintThe distance of the member's parent from the root level of the hierarchy. The root level is zero (0).NoNo
DESCRIPTIONstringThis column always returns a NULL value. This column exists for backwards compatibilityNoNo
EXPRESSIONstringThe expression for calculations, if the member is of type MDMEMBER_TYPE_FORMULA.NoNo
MEMBER_KEYstringThe value of the member's key column. Returns NULL if the member has a composite key.NoNo
+ * @method discoverMDMembers + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_MEMBERS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_MEMBERS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDMembers: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_MEMBERS + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_PROPERTIES schema rowset. + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the database.YesNo
SCHEMA_NAMEstringThe name of the schema to which this property belongs. NULL if the provider does not support schemas.YesYes
CUBE_NAMEstringThe name of the cube.YesYes
DIMENSION_UNIQUE_NAMEstringThe unique name of the dimension. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
HIERARCHY_UNIQUE_NAMEstringThe unique name of the hierarchy. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
LEVEL_UNIQUE_NAMEstringThe unique name of the level to which this property belongs. If the provider does not support named levels, it should return the DIMENSION_UNIQUE_NAME value for this field. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
MEMBER_UNIQUE_NAMEstringThe unique name of the member to which the property belongs. Used for data stores that do not support named levels or have properties on a member-by-member basis. If the property applies to all members in a level, this column is NULL. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
PROPERTY_TYPEintA bitmap that specifies the type of the property: + *
+ *
MDPROP_MEMBER (1)
identifies a property of a member. This property can be used in the DIMENSION PROPERTIES clause of the SELECT statement.
+ *
MDPROP_CELL (2)
identifies a property of a cell. This property can be used in the CELL PROPERTIES clause that occurs at the end of the SELECT statement.
+ *
MDPROP_SYSTEM (4)
identifies an internal property.
+ *
MDPROP_BLOB (8)
identifies a property which contains a binary large object (blob).
+ *
+ *
YesYes
PROPERTY_NAMEstringThe name of the property. If the key for the property is the same as the name for the property, PROPERTY_NAME will be blank.YesYes
PROPERTY_CAPTIONstringA label or caption associated with the property, used primarily for display purposes. Returns PROPERTY_NAME if a caption does not exist.NoYes
DATA_TYPEintThe data type of the property.NoYes
CHARACTER_MAXIMUM_LENGTHintThe maximum possible length of the property, if it is a character, binary, or bit type. Zero indicates there is no defined maximum length. Returns NULL for all other data types.NoYes
CHARACTER_OCTET_LENGTHintThe maximum possible length (in bytes) of the property, if it is a character or binary type. Zero indicates there is no defined maximum length. Returns NULL for all other data types.NoYes
NUMERIC_PRECISIONintThe maximum precision of the property, if it is a numeric data type. Returns NULL for all other data types.NoYes
NUMERIC_SCALEintThe number of digits to the right of the decimal point, if it is a DBTYPE_NUMERIC or DBTYPE_DECIMAL type. Returns NULL for all other data types.NoYes
DESCRIPTIONstringA human readable description of the property. NULL if no description exists.NoYes
PROPERTY_CONTENT_TYPEintThe type of the property. Can be one of the following enumerations: + * YesYes
SQL_COLUMN_NAMEstringThe name of the property used in SQL queries from the cube dimension or database dDimension.NoYes
LANGUAGEintThe translation expressed as an LCID. Only valid for property translations.NoYes
PROPERTY_ORIGINintIdentifies the type of hierarchy that the property applies to:YesYes
PROPERTY_ATTRIBUTE_HIERARCHY_NAMEstringThe name of the attribute hierarchy sourcing this property.NoYes
PROPERTY_CARDINALITYstringThe cardinality of the property. Possible values include the following strings: ONE or MANYNoYes
MIME_TYPEstringThe mime type for binary large objects (BLOBs).NoYes
PROPERTY_IS_VISIBLEbooleanA Boolean that indicates whether the property is visible. TRUE if the property is visible; otherwise, FALSE.NoYes
+ * @method discoverMDProperties + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_PROPERTIES request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_PROPERTIES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDProperties: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_PROPERTIES + }, true); + return this.discover(request); + }, + /** + * Invokes the discover() method using + * as value for the requestType, + * and retrieves the MDSCHEMA_SETS schema rowset. + * ...todo... + * The rowset has the following columns: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the catalog to which this set belongs.YesNo
SCHEMA_NAMEstringThe name of the schema to which this property belongs. NULL if the provider does not support schemas.YesYes
CUBE_NAMEstringThe name of the cube to which the set belongs. This column always contains a value and can never be null.YesNo
SET_NAMEstringThe name of the set.YesNo
SCOPEstringThe scope of the set.YesNo
DESCRIPTIONstringNoYes
EXPRESSIONstringThe expression for this set.NoNo
DIMENSIONSstringA comma separated list of dimensions used by this set.NoYes
+ * @method discoverMDSets + * @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_SETS request. + * @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_SETS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. + */ + discoverMDSets: function(options){ + var request = _applyProps(options, { + requestType: Xmla.MDSCHEMA_SETS + }, true); + return this.discover(request); } - if (!request.properties) { - request.properties = {}; + }; + + function _getComplexType(node, name){ + var types = _getElementsByTagNameNS(node, _xmlnsSchema, _xmlnsSchemaPrefix, "complexType"), + numTypes = types.length, + type, i + ; + for (i = 0; i < numTypes; i++){ + type = types[i]; + if (_getAttribute(type, "name")===name) return type; } - request.properties[Xmla.PROP_FORMAT] = Xmla.PROP_FORMAT_TABULAR; - return this.request(request); - }, -/** -* Invokes the discover() method using as value for the requestType, -* and retrieves the DISCOVER_DATASOURCES schema rowset. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
-* DataSourceName -* -* string -* -* A name that identifies this data source. -* -* Yes -* -* No -*
-* DataSourceDescription -* -* string -* -* Human readable description of the datasource -* -* No -* -* Yes -*
-* URL -* -* string -* -* URL to use to submit requests to this provider. -* -* Yes -* -* Yes -*
-* DataSourceInfo -* -* string -* -* Connectstring -* -* No -* -* Yes -*
-* ProviderName -* -* string -* -* A name indicating the product providing the XML/A implementation -* -* Yes -* -* Yes -*
-* ProviderType -* -* string[] -* -* The kind of data sets supported by this provider. -* The following values are defined by the XML/A specification: -*
-*
TDP
tabular data provider.
-*
MDP
multidimensiona data provider.
-*
DMP
data mining provider.
-*
-* Note: multiple values are possible. -*
-* Yes -* -* No -*
-* AuthenticationMode -* -* string -* -* Type of security offered by the provider -* The following values are defined by the XML/A specification: -*
-*
Unauthenticated
no user ID or password needs to be sent.
-*
Authenticated
User ID and password must be included in the information required for the connection.
-*
Integrated
the data source uses the underlying security to determine authorization
-*
-*
-* Yes -* -* No -*
-* -* @method discoverDataSources -* @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_DATASOURCES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_DATASOURCES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDataSources: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DISCOVER_DATASOURCES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using as value for the requestType, -* and retrieves the DISCOVER_PROPERTIES schema rowset. -* This rowset provides information on the properties that are supported by the XML/A provider. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
-* PropertyName -* -* string -* -* The name of the property -* -* Yes (array) -* -* No -*
-* PropertyDescription -* -* string -* -* Human readable description of the property -* -* No -* -* Yes -*
-* PropertyType -* -* string -* -* The property's datatype (as an XML Schema data type) -* -* No -* -* Yes -*
-* PropertyAccessType -* -* string -* -* How the property may be accessed. Values defined by the XML/A spec are: -*
    -*
  • Read
  • -*
  • Write
  • -*
  • ReadWrite
  • -*
-*
-* No -* -* No -*
-* IsRequired -* -* boolean -* -* true if the property is required, false if not. -* -* No -* -* Yes -*
-* Value -* -* string -* -* The property's current value. -* -* No -* -* Yes -*
-* -* @method discoverProperties -* @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_DATASOURCES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_DATASOURCES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverProperties: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DISCOVER_PROPERTIES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using as value for the requestType, -* and retrieves the DISCOVER_SCHEMA_ROWSETS schema rowset. -* This rowset lists all possible request types supported by this provider. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
SchemaNamestringThe requestType. YesNo
RestrictionsarrayA list of columns that may be used to filter the schema rowset.NoYes
DescriptionstringA human readable description of the schema rowset that is returned when using this requestTypeNoYes
-* -* @method discoverSchemaRowsets -* @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_SCHEMA_ROWSETS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_DATASOURCES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverSchemaRowsets: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DISCOVER_SCHEMA_ROWSETS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using as value for the requestType, -* and retrieves the DISCOVER_ENUMERATORS schema rowset. -* This rowset lists the names, data types, and enumeration values of enumerators supported by the XMLA Provider for a specific data source. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
EnumNamestringName of the enumerator. Yes (array)No
EnumDescriptionstringA human readable description of the enumeratorNoYes
EnumTypestringThe XML Schema data type of this enumeratorNoNo
ElementNamestringThe name of the enumerator entryNoNo
ElementDescriptionstringA human readable description of this enumerator entryNoYes
ElementValuestringThe value of this enumerator entryNoYes
-* -* @method discoverEnumerators -* @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_ENUMERATORS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_ENUMERATORS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverEnumerators: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DISCOVER_ENUMERATORS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using as value for the requestType, -* and retrieves the DISCOVER_KEYWORDS schema rowset. -* This rowset is a list of reserved words for this XML/A provider. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
KeywordstringName of the enumerator. Yes (array)No
-* -* @method discoverKeywords -* @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_KEYWORDS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_ENUMERATORS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverKeywords: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DISCOVER_KEYWORDS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using as value for the requestType, -* and retrieves the DISCOVER_LITERALS schema rowset. -* This rowset is a list of reserved words for this XML/A provider. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
LiteralNamestringName of the literal. Yes (array)No
LiteralValuestringThe actual literal value. NoYes
LiteralInvalidCharsstringCharacters that may not appear in the literal NoYes
LiteralInvalidStartingCharsstringCharacters that may not appear as first character in the literal NoYes
LiteralMaxLengthintmaximum number of characters for this literal, or -1 in case there is no maximum, or the maximum is unknownNoYes
-* -* @method discoverLiterals -* @param {Object} options An object whose properties convey the options for the XML/A a DISCOVER_LITERALS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DISCOVER_LITERALS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverLiterals: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DISCOVER_LITERALS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the DBSCHEMA_CATALOGS schema rowset. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
DESCRIPTIONstringHuman readable descriptionNoYes
ROLESstringA comma-separatd list of roles available to the current user.NoYes
DATE_MODIFIEDDateThe date this catalog was modifiedNoYes
-* @method discoverDBCatalogs -* @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_CATALOGS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_CATALOGS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDBCatalogs: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DBSCHEMA_CATALOGS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the DBSCHEMA_COLUMNS schema rowset. -* Provides column information for all columns meeting the provided restriction criteria. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
TABLE_CATALOGstringThe name of the Database.YesNo
TABLE_SCHEMAstringNot supported.YesNo
TABLE_NAMEstringThe name of the cube.YesNo
COLUMN_NAMEstringThe name of the attribute hierarchy or measure.YesNo
COLUMN_GUIDstringNot supported.NoNo
COLUMN_PROPIDintNot supported.NoNo
ORDINAL_POSITIONintThe position of the column, beginning with 1.NoNo
COLUMN_HAS_DEFAULTbooleanNot supported.NoNo
COLUMN_DEFAULTstringNot supported.NoNo
COLUMN_FLAGSintA DBCOLUMNFLAGS bitmask indicating column properties. See 'DBCOLUMNFLAGS Enumerated Type' in IColumnsInfo::GetColumnInfoNoNo
IS_NULLABLEbooleanAlways returns false.NoNo
DATA_TYPEstringThe data type of the column. Returns a string for dimension columns and a variant for measures.NoNo
TYPE_GUID -* srringNot supported.NoNo
CHARACTER_MAXIMUM_LENGTHintThe maximum possible length of a value within the column. This is retrieved from the DataSize property in the DataItem.NoNo
CHARACTER_OCTET_LENGTHintThe maximum possible length of a value within the column, in bytes, for character or binary columns. A value of zero (0) indicates the column has no maximum length. NULL will be returned for columns that do not return binary or character data types.NoNo
NUMERIC_PRECISIONintThe maximum precision of the column for numeric data types other than DBTYPE_VARNUMERIC.NoNo
NUMERIC_SCALEintThe number of digits to the right of the decimal point for DBTYPE_DECIMAL, DBTYPE_NUMERIC, DBTYPE_VARNUMERIC. Otherwise, this is NULL.NoNo
DATETIME_PRECISIONintNot supported.NoNo
CHARACTER_SET_CATALOGstringNot supported.NoNo
CHARACTER_SET_SCHEMAstringNot supported.NoNo
CHARACTER_SET_NAMEstringNot supported.NoNo
COLLATION_CATALOGstringNot supported.NoNo
COLLATION_SCHEMAstringNot supported.NoNo
COLLATION_NAMEstringNot supported.NoNo
DOMAIN_CATALOGstringNot supported.NoNo
DOMAIN_SCHEMAstringNot supported.NoNo
DOMAIN_NAMEstringNot supported.NoNo
DESCRIPTIONstringNot supported.NoNo
COLUMN_OLAP_TYPEstringThe OLAP type of the object. MEASURE indicates the object is a measure. ATTRIBUTE indicates the object is a dimension attribute.YesNo
-* The rowset is sorted on TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME. -* @method discoverDBColumns -* @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_COLUMNS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_COLUMNS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDBColumns: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DBSCHEMA_COLUMNS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the DBSCHEMA_PROVIDER_TYPES schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
TYPE_NAMEstringThe provider-specific data type name.falsetrue
DATA_TYPEintThe indicator of the data type.falsetrue
COLUMN_SIZEint The length of a non-numeric column or parameter that refers to either the maximum or the length defined for this type by the provider. For character data, this is the maximum or defined length in characters. For DateTime data types, this is the length of the string representation (assuming the maximum allowed precision of the fractional seconds component). If the data type is numeric, this is the upper bound on the maximum precision of the data type. falsetrue
LITERAL_PREFIXstringThe character or characters used to prefix a literal of this type in a text command.falsetrue
LITERAL_SUFFIXstringThe character or characters used to suffix a literal of this type in a text command.falsetrue
CREATE_PARAMS -* stringThe creation parameters specified by the consumer when creating a column of this data type. For example, the SQL data type, DECIMAL, needs a precision and a scale. In this case, the creation parameters might be the string "precision,scale". In a text command to create a DECIMAL column with a precision of 10 and a scale of 2, the value of the TYPE_NAME column might be DECIMAL() and the complete type specification would be DECIMAL(10,2). The creation parameters appear as a comma-separated list of values, in the order they are to be supplied and with no surrounding parentheses. If a creation parameter is length, maximum length, precision, scale, seed, or increment, use "length", "max length", "precision", "scale", "seed", and "increment", respectively. If the creation parameter is some other value, the provider determines what text is to be used to describe the creation parameter. If the data type requires creation parameters, "()" usually appears in the type name. This indicates the position at which to insert the creation parameters. If the type name does not include "()", the creation parameters are enclosed in parentheses and appended to the data type name. falsetrue
IS_NULLABLEbooleanA Boolean that indicates whether the data type is nullable. VARIANT_TRUE indicates that the data type is nullable. VARIANT_FALSE indicates that the data type is not nullable. NULL indicates that it is not known whether the data type is nullable.falsetrue
CASE_SENSITIVEbooleanA Boolean that indicates whether the data type is a characters type and case-sensitive. VARIANT_TRUE indicates that the data type is a character type and is case-sensitive. VARIANT_FALSE indicates that the data type is not a character type or is not case-sensitive.falsetrue
SEARCHABLEintAn integer indicating how the data type can be used in searches if the provider supports ICommandText; otherwise, NULL. This column can have the following values: DB_UNSEARCHABLE indicates that the data type cannot be used in a WHERE clause. DB_LIKE_ONLY indicates that the data type can be used in a WHERE clause only with the LIKE predicate.DB_ALL_EXCEPT_LIKE indicates that the data type can be used in a WHERE clause with all comparison operators except LIKE. DB_SEARCHABLE indicates that the data type can be used in a WHERE clause with any comparison operator.falsetrue
UNSIGNED_ATTRIBUTEbooleanA Boolean that indicates whether the data type is unsigned. VARIANT_TRUE indicates that the data type is unsigned. VARIANT_FALSE indicates that the data type is signed.NULL indicates that this is not applicable to the data type.falsetrue
FIXED_PREC_SCALEbooleanA Boolean that indicates whether the data type has a fixed precision and scale. VARIANT_TRUE indicates that the data type has a fixed precision and scale. VARIANT_FALSE indicates that the data type does not have a fixed precision and scale.falsetrue
AUTO_UNIQUE_VALUEbooleanA Boolean that indicates whether the data type is autoincrementing. VARIANT_TRUE indicates that values of this type can be autoincrementing. VARIANT_FALSE indicates that values of this type cannot be autoincrementing. If this value is VARIANT_TRUE, whether or not a column of this type is always autoincrementing depends on the provider's DBPROP_COL_AUTOINCREMENT column property. If the DBPROP_COL_AUTOINCREMENT property is read/write, whether or not a column of this type is autoincrementing depends on the setting of the DBPROP_COL_AUTOINCREMENT property. If DBPROP_COL_AUTOINCREMENT is a read-only property, either all or none of the columns of this type are autoincrementing. falsetrue
LOCAL_TYPE_NAMEstringThe localized version of TYPE_NAME. NULL is returned if a localized name is not supported by the data provider.falsetrue
MINIMUM_SCALEintIf the type indicator is DBTYPE_VARNUMERIC, DBTYPE_DECIMAL, or DBTYPE_NUMERIC, the minimum number of digits allowed to the right of the decimal point. Otherwise, NULL.falsetrue
MAXIMUM_SCALEintThe maximum number of digits allowed to the right of the decimal point if the type indicator is DBTYPE_VARNUMERIC, DBTYPE_DECIMAL, or DBTYPE_NUMERIC; otherwise, NULL.falsetrue
GUIDstring(Intended for future use) The GUID of the type, if the type is described in a type library. Otherwise, NULL.falsetrue
TYPELIB -* string(Intended for future use) The type library containing the description of the type, if the type is described in a type library. Otherwise, NULL.falsetrue
VERSIONstring(Intended for future use) The version of the type definition. Providers might want to version type definitions. Different providers might use different versioning schemes, such as a timestamp or number (integer or float). NULL if not supported.falsetrue
IS_LONGbooleanA Boolean that indicates whether the data type is a binary large object (BLOB) and has very long data. VARIANT_TRUE indicates that the data type is a BLOB that contains very long data; the definition of very long data is provider-specific. VARIANT_FALSE indicates that the data type is a BLOB that does not contain very long data or is not a BLOB. This value determines the setting of the DBCOLUMNFLAGS_ISLONG flag returned by GetColumnInfo in IColumnsInfo and GetParameterInfo in ICommandWithParameters.falsetrue
BEST_MATCHbooleanA Boolean that indicates whether the data type is a best match. VARIANT_TRUE indicates that the data type is the best match between all data types in the data store and the OLE DB data type indicated by the value in the DATA_TYPE column. VARIANT_FALSE indicates that the data type is not the best match. For each set of rows in which the value of the DATA_TYPE column is the same, the BEST_MATCH column is set to VARIANT_TRUE in only one row.falsetrue
IS_FIXEDLENGTHbooleanA Boolean that indicates whether the column is fixed in length. VARIANT_TRUE indicates that columns of this type created by the data definition language (DDL) will be of fixed length. VARIANT_FALSE indicates that columns of this type created by the DDL will be of variable length. If the field is NULL, it is not known whether the provider will map this field with a fixed-length or variable-length column. -* falsetrue
-* @method discoverDBProviderTypes -* @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_PROVIDER_TYPES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_PROVIDER_TYPES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDBProviderTypes: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DBSCHEMA_PROVIDER_TYPES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the DBSCHEMA_SCHEMATA schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
-* @method discoverDBSchemata -* @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_SCHEMATA request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_SCHEMATA schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDBSchemata: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DBSCHEMA_SCHEMATA - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the DBSCHEMA_TABLES schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
-* @method discoverDBTables -* @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_TABLES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_TABLES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDBTables: function(options){ - var request = _applyProps(options, { - requestType: Xmla.DBSCHEMA_TABLES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the DBSCHEMA_TABLES_INFO schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
-* @method discoverDBTablesInfo -* @param {Object} options An object whose properties convey the options for the XML/A a DBSCHEMA_TABLES_INFO request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the DBSCHEMA_TABLES_INFO schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverDBTablesInfo: function(options){ - var request = _applyProps( - options, - { - requestType: Xmla.DBSCHEMA_TABLES_INFO - }, - true - ); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_ACTIONS schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
-* @method discoverMDActions -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_ACTIONS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_ACTIONS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDActions: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_ACTIONS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_CUBES schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
CUBE_TYPEstringType of the cube.NoNo
CUBE_GUIDstringNot supportedNoNo
CREATED_ONDateNot supportedNoNo
LAST_SCHEMA_UPDATEDateThe time that the cube was last processed.NoNo
SCHEMA_UPDATED_BYstringNoNo
LAST_DATA_UPDATEDateThe time that the cube was last processed.NoNo
DATA_UPDATED_BYstringNoNo
DESCRIPTIONstringA Human-readable description of the cube.NoNo
IS_DRILLTHROUGH_ENABLEDbooleanNoNo
IS_LINKABLEbooleanNoNo
IS_WRITE_ENABLEDbooleanNoNo
IS_SQL_ENABLEDbooleanNoNo
CUBE_CAPTIONstringCaption for this cube.NoNo
BASE_CUBE_NAMEstringName of the source cube (if this cube is a perspective cube).YesNo
ANNOTATIONSstringNotes in xml formatNoNo
-* @method discoverMDCubes -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_CUBES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_CUBES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDCubes: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_CUBES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_DIMENSIONS schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
DIMENSION_NAMEstringName of the dimension.YesNo
DIMENSION_UNIQUE_NAMEstringUnique name for this dimension.YesNo
DIMENSION_GUIDstringNoYes
DIMENSION_CAPTIONstringNoYes
DIMENSION_ORDINALintNoYes
DIMENSION_TYPEstring -*
    -*
  • MD_DIMTYPE_UNKNOWN (0)
  • -*
  • MD_DIMTYPE_TIME (1)
  • -*
  • MD_DIMTYPE_MEASURE (2)
  • -*
  • MD_DIMTYPE_OTHER (3)
  • -*
  • MD_DIMTYPE_QUANTITATIVE (5)
  • -*
  • MD_DIMTYPE_ACCOUNTS (6)
  • -*
  • MD_DIMTYPE_CUSTOMERS (7)
  • -*
  • MD_DIMTYPE_PRODUCTS (8)
  • -*
  • MD_DIMTYPE_SCENARIO (9)
  • -*
  • MD_DIMTYPE_UTILIY (10)
  • -*
  • MD_DIMTYPE_CURRENCY (11)
  • -*
  • MD_DIMTYPE_RATES (12)
  • -*
  • MD_DIMTYPE_CHANNEL (13)
  • -*
  • MD_DIMTYPE_PROMOTION (14)
  • -*
  • MD_DIMTYPE_ORGANIZATION (15)
  • -*
  • MD_DIMTYPE_BILL_OF_MATERIALS (16)
  • -*
  • MD_DIMTYPE_GEOGRAPHY (17)
  • -*
-*
NoYes
DIMENSION_CARDINALITYintNoYes
DEFAULT_HIERARCHYstringNoYes
DESCRIPTIONstringA Human-readable description of the dimension.NoNo
IS_VIRTUALbooleanNoNo
IS_READWRITEbooleanNoNo
DIMENSION_UNIQUE_SETTINGSNoNo
DIMENSION_MASTER_UNIQUE_NAMENoNo
DIMENSION_IS_VISIBLEbooleanNoNo
-* @method discoverMDDimensions -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_DIMENSIONS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_DIMENSIONS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDDimensions: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_DIMENSIONS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_FUNCTIONS schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
FUNCTION_NAMEDBTYPE_WSTRThe name of the function.YesYes
DESCRIPTIONDBTYPE_WSTRA description of the function.NoNo
PARAMETER_LISTDBTYPE_WSTRA comma delimited list of parameters formatted as in Microsoft Visual Basic. For example, a parameter might be Name as String.NoNo
RETURN_TYPEDBTYPE_I4The VARTYPE of the return data type of the function.NoNo
ORIGINDBTYPE_I4The origin of the function: -*
    -*
  1. for MDX functions.
  2. -*
  3. for user-defined functions.
  4. -*
-*
YesYes
INTERFACE_NAMEDBTYPE_WSTRThe name of the interface for user-defined functions. The group name for Multidimensional Expressions (MDX) functions.YesYes
LIBRARY_NAMEDBTYPE_WSTRThe name of the type library for user-defined functions. NULL for MDX functions.YesYes
DLL_NAMEDBTYPE_WSTR(Optional) The name of the assembly that implements the user-defined function. Returns VT_NULL for MDX functions.NoNo
HELP_FILEDBTYPE_WSTR(Optional) The name of the file that contains the help documentation for the user-defined function.Returns VT_NULL for MDX functions.NoNo
HELP_CONTEXTDBTYPE_I4(Optional) Returns the Help context ID for this function.NoNo
OBJECTDBTYPE_WSTR -* (Optional) The generic name of the object class to which a property applies. For example, the rowset corresponding to the .Members function returns "Level". -* Returns VT_NULL for user-defined functions, or non-property MDX functions. -* NoNo
CAPTIONDBTYPE_WSTRThe display caption for the function.NoNo
-* @method discoverMDFunctions -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_FUNCTIONS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_FUNCTIONS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDFunctions: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_FUNCTIONS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_HIERARCHIES schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
DIMENSION_UNIQUE_NAMEstringUnique name for this dimension.YesNo
HIERARCHY_NAMEstringName of the hierarchy.YesNo
HIERARCHY_UNIQUE_NAMEstringUnique name for this hierarchy.YesNo
HIERARCHY_GUIDstringNoYes
HIERARCHY_CAPTIONstringNoYes
DIMENSION_TYPEstringNoYes
HIERARCHY_CARDINALITYintNoYes
DEFAULT_MEMBERstringNoYes
ALL_MEMBERstringNoYes
DESCRIPTIONstringA Human-readable description of the dimension.NoNo
STRUCTUREstringNoYes
IS_VIRTUALbooleanNoYes
IS_READWRITEbooleanNoYes
DIMENSION_UNIQUE_SETTINGSstringNoYes
DIMENSION_MASTER_UNIQUE_NAMEstringNoYes
DIMENSION_IS_VISIBLEbooleanNoYes
HIERARCHY_ORDINALintNoYes
DIMENSION_IS_SHAREDbooleanNoYes
HIERARCHY_IS_VISIBLEbooleanNoYes
HIERARCHY_ORIGINYesYes
HIERARCHY_DISPLAY_FOLDERstringNoYes
INSTANCE_SELECTIONstringNoYes
-* @method discoverMDHierarchies -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_HIERARCHIES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_HIERARCHIES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDHierarchies: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_HIERARCHIES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_LEVELS schema rowset. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the catalog to which this level belongs. NULL if the provider does not support catalogs.YesYes
SCHEMA_NAMEstringThe name of the schema to which this level belongs. NULL if the provider does not support schemas.YesYes
CUBE_NAMEstringThe name of the cube to which this level belongs.YesYes
DIMENSION_UNIQUE_NAMEstringThe unique name of the dimension to which this level belongs. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
HIERARCHY_UNIQUE_NAMEstringThe unique name of the hierarchy. If the level belongs to more than one hierarchy, there is one row for each hierarchy to which it belongs. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
LEVEL_NAMEstringThe name of the level.YesYes
LEVEL_UNIQUE_NAMEstringThe properly escaped unique name of the level.YesYes
LEVEL_GUIDstringNot supported.NoYes
LEVEL_CAPTIONstringA label or caption associated with the hierarchy. Used primarily for display purposes. If a caption does not exist, LEVEL_NAME is returned.NoYes
LEVEL_NUMBERintThe distance of the level from the root of the hierarchy. Root level is zero (0).NoYes
LEVEL_CARDINALITYintThe number of members in the level.NoYes
LEVEL_TYPEintType of the level: -*
    -*
  • MDLEVEL_TYPE_REGULAR (0x0000)
  • -*
  • MDLEVEL_TYPE_ALL (0x0001)
  • -*
  • MDLEVEL_TYPE_TIME_YEARS (0x0014)
  • -*
  • MDLEVEL_TYPE_TIME_HALF_YEAR (0x0024)
  • -*
  • MDLEVEL_TYPE_TIME_QUARTERS (0x0044)
  • -*
  • MDLEVEL_TYPE_TIME_MONTHS (0x0084)
  • -*
  • MDLEVEL_TYPE_TIME_WEEKS (0x0104)
  • -*
  • MDLEVEL_TYPE_TIME_DAYS (0x0204)
  • -*
  • MDLEVEL_TYPE_TIME_HOURS (0x0304)
  • -*
  • MDLEVEL_TYPE_TIME_MINUTES (0x0404)
  • -*
  • MDLEVEL_TYPE_TIME_SECONDS (0x0804)
  • -*
  • MDLEVEL_TYPE_TIME_UNDEFINED (0x1004)
  • -*
  • MDLEVEL_TYPE_GEO_CONTINENT (0x2001)
  • -*
  • MDLEVEL_TYPE_GEO_REGION (0x2002)
  • -*
  • MDLEVEL_TYPE_GEO_COUNTRY (0x2003)
  • -*
  • MDLEVEL_TYPE_GEO_STATE_OR_PROVINCE (0x2004)
  • -*
  • MDLEVEL_TYPE_GEO_COUNTY (0x2005)
  • -*
  • MDLEVEL_TYPE_GEO_CITY (0x2006)
  • -*
  • MDLEVEL_TYPE_GEO_POSTALCODE (0x2007)
  • -*
  • MDLEVEL_TYPE_GEO_POINT (0x2008)
  • -*
  • MDLEVEL_TYPE_ORG_UNIT (0x1011)
  • -*
  • MDLEVEL_TYPE_BOM_RESOURCE (0x1012)
  • -*
  • MDLEVEL_TYPE_QUANTITATIVE (0x1013)
  • -*
  • MDLEVEL_TYPE_ACCOUNT (0x1014)
  • -*
  • MDLEVEL_TYPE_CUSTOMER (0x1021)
  • -*
  • MDLEVEL_TYPE_CUSTOMER_GROUP (0x1022)
  • -*
  • MDLEVEL_TYPE_CUSTOMER_HOUSEHOLD (0x1023)
  • -*
  • MDLEVEL_TYPE_PRODUCT (0x1031)
  • -*
  • MDLEVEL_TYPE_PRODUCT_GROUP (0x1032)
  • -*
  • MDLEVEL_TYPE_SCENARIO (0x1015)
  • -*
  • MDLEVEL_TYPE_UTILITY (0x1016)
  • -*
  • MDLEVEL_TYPE_PERSON (0x1041)
  • -*
  • MDLEVEL_TYPE_COMPANY (0x1042)
  • -*
  • MDLEVEL_TYPE_CURRENCY_SOURCE (0x1051)
  • -*
  • MDLEVEL_TYPE_CURRENCY_DESTINATION (0x1052)
  • -*
  • MDLEVEL_TYPE_CHANNEL (0x1061)
  • -*
  • MDLEVEL_TYPE_REPRESENTATIVE (0x1062)
  • -*
  • MDLEVEL_TYPE_PROMOTION (0x1071)
  • -*
-* Some of the OLE DB for OLAP values are as flags, and do not become values of the enumeration: -*
    -*
  • MDLEVEL_TYPE_UNKNOWN (0x0000) signals that no other flags are set.
  • -*
  • MDLEVEL_TYPE_CALCULATED (0x0002) indicates that the level is calculated.
  • -*
  • MDLEVEL_TYPE_TIME (0x0004) indicates that the level is time-related.
  • -*
  • MDLEVEL_TYPE_RESERVED1 (0x0008) is reserved for future use.
  • -*
-*
NoYes
DESCRIPTIONstringA human-readable description of the level. NULL if no description exists.NoYes
CUSTOM_ROLLUP_SETTINGSintA bitmap that specifies the custom rollup options: -*
    -*
  • MDLEVELS_CUSTOM_ROLLUP_EXPRESSION (0x01) indicates an expression exists for this level. (Deprecated)
  • -*
  • MDLEVELS_CUSTOM_ROLLUP_COLUMN (0x02) indicates that there is a custom rollup column for this level.
  • -*
  • MDLEVELS_SKIPPED_LEVELS (0x04) indicates that there is a skipped level associated with members of this level.
  • -*
  • MDLEVELS_CUSTOM_MEMBER_PROPERTIES (0x08) indicates that members of the level have custom member properties.
  • -*
  • MDLEVELS_UNARY_OPERATOR (0x10) indicates that members on the level have unary operators.
  • -*
-*
NoYes
LEVEL_UNIQUE_SETTINGSintA bitmap that specifies which columns contain unique values, if the level only has members with unique names or keys. -* The Msmd.h file defines the following bit value constants for this bitmap: -*
    -*
  • MDDIMENSIONS_MEMBER_KEY_UNIQUE (1)
  • -*
  • MDDIMENSIONS_MEMBER_NAME_UNIQUE (2)
  • -*
-* The key is always unique in Microsoft SQL Server 2005 Analysis Services (SSAS). -* The name will be unique if the setting on the attribute is UniqueInDimension or UniqueInAttribute -*
NoYes
LEVEL_IS_VISIBLEboolA Boolean that indicates whether the level is visible. Always returns True. If the level is not visible, it will not be included in the schema rowset.NoYes
LEVEL_ORDERING_PROPERTYstringThe ID of the attribute that the level is sorted on.NoYes
LEVEL_DBTYPEintThe DBTYPE enumeration of the member key column that is used for the level attribute. Null if concatenated keys are used as the member key column.NoYes
LEVEL_MASTER_UNIQUE_NAMEstringAlways returns NULL.NoYes
LEVEL_NAME_SQL_COLUMN_NAMEstringThe SQL representation of the level member names.NoYes
LEVEL_KEY_SQL_COLUMN_NAMEstringThe SQL representation of the level member key values.NoYes
LEVEL_UNIQUE_NAME_SQL_COLUMN_NAMEstringThe SQL representation of the member unique names.NoYes
LEVEL_ATTRIBUTE_HIERARCHY_NAMEstringThe name of the attribute hierarchy providing the source of the level.NoYes
LEVEL_KEY_CARDINALITYintThe number of columns in the level key.NoYes
LEVEL_ORIGINintA bit map that defines how the level was sourced:MD_ORIGIN_USER_DEFINED identifies levels in a user defined hierarchy.MD_ORIGIN_ATTRIBUTE identifies levels in an attribute hierarchy.MD_ORIGIN_KEY_ATTRIBUTE identifies levels in a key attribute hierarchy.MD_ORIGIN_INTERNAL identifies levels in attribute hierarchies that are not enabled.NoYes
-* @method discoverMDLevels -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_LEVELS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_LEVELS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDLevels: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_LEVELS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_MEASURES schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringName of the catalogYesNo
SCHEMA_NAMEstringNot supportedYesYes
CUBE_NAMEstringName of the cube.YesNo
MEASURE_NAMEstringThe name of the measure.YesNo
MEASURE_UNIQUE_NAMEstringThe Unique name of the measure. For providers that generate unique names by qualification, each component of this name is delimited.YesNo
MEASURE_CAPTIONstringA label or caption associated with the measure. Used primarily for display purposes. If a caption does not exist, MEASURE_NAME is returned.NoNo
MEASURE_GUIDstringNot supported.NoNo
MEASURE_AGGREGATORintAn enumeration that indicates how the measure was derived. See http://msdn.microsoft.com/en-us/library/ms126250.aspxNoNo
DATA_TYPEintThe data type of the measure. Valid values are: -*
-*
DBTYPE_EMPTY
0
-*
DBTYPE_NULL
1
-*
DBTYPE_I2
2
-*
DBTYPE_I4
3
-*
DBTYPE_R4
4
-*
DBTYPE_R8
5
-*
DBTYPE_CY
6
-*
DBTYPE_DATE
7
-*
DBTYPE_BSTR
8
-*
DBTYPE_IDISPATCH
9
-*
DBTYPE_ERROR
10
-*
DBTYPE_BOOL
11
-*
DBTYPE_VARIANT
12
-*
DBTYPE_IUNKNOWN
13
-*
DBTYPE_DECIMAL
14
-*
DBTYPE_UI1
17
-*
DBTYPE_ARRAY
0x2000
-*
DBTYPE_BYREF
0x4000
-*
DBTYPE_I1
16
-*
DBTYPE_UI2
18
-*
DBTYPE_UI4
19
-*
DBTYPE_I8
20
-*
DBTYPE_UI8
21
-*
DBTYPE_GUID
72
-*
DBTYPE_VECTOR
0x1000
-*
DBTYPE_FILETIME
64
-*
DBTYPE_RESERVED
0x8000
-*
DBTYPE_BYTES
128
-*
DBTYPE_STR
129
-*
DBTYPE_WSTR
130
-*
DBTYPE_NUMERIC
131
-*
DBTYPE_UDT
132
-*
DBTYPE_DBDATE
133
-*
DBTYPE_DBTIME
134
-*
DBTYPE_DBTIMESTAMP
135
-*
DBTYPE_HCHAPTER
136
-*
DBTYPE_PROPVARIANT
138
-*
DBTYPE_VARNUMERIC
139
-*
-* See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms711251(v=vs.85).aspx
NoNo
NUMERIC_PRECISIONintThe maximum precision of the property if the measure object's data type is exact numeric. NULL for all other property types.NoNo
NUMERIC_SCALEintThe number of digits to the right of the decimal point if the measure object's type indicator is DBTYPE_NUMERIC or DBTYPE_DECIMAL. Otherwise, this value is NULL.NoNo
MEASURE_UNITSintNot supported.NoNo
DESCRIPTIONstringA human-readable description of the measure. NULL if no description exists.NoNo
EXPRESSIONstringAn expression for the member.NoNo
MEASURE_IS_VISIBLEbooleanA Boolean that always returns True. If the measure is not visible, it will not be included in the schema rowset.NoNo
LEVELS_LISTstringA string that always returns NULL.NoNo
MEASURE_NAME_SQL_COLUMN_NAMEstringThe name of the column in the SQL query that corresponds to the measure's name.NoNo
MEASURE_UNQUALIFIED_CAPTIONstringThe name of the measure, not qualified with the measure group name.NoNo
MEASUREGROUP_NAMEstringThe name of the measure group to which the measure belongs.YesNo
MEASURE_DISPLAY_FOLDERstringThe path to be used when displaying the measure in the user interface. Folder names will be separated by a semicolon. Nested folders are indicated by a backslash (\).NoNo
DEFAULT_FORMAT_STRINGstringThe default format string for the measure.NoNo
-* @method discoverMDMeasures -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_MEASURES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_MEASURES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDMeasures: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_MEASURES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_MEMBERS schema rowset. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the catalogYesNo
SCHEMA_NAMEstringThe name of the schemaYesNo
CUBE_NAMEstringThe name of the cubeYesNo
DIMENSION_UNIQUE_NAMEstringThe unique name of the dimensionYesNo
HIERARCHY_UNIQUE_NAMEstringThe unique name of the hierarchyYesNo
LEVEL_UNIQUE_NAMEstringThe unique name of the levelYesNo
LEVEL_NUMBERintDistance of this level to the rootYesNo
MEMBER_ORDINALintDeprecated: always 0NoNo
MEMBER_NAMEstringThe name of this memberYesNo
MEMBER_UNIQUE_NAMEstringThe unique name of this memberYesNo
MEMBER_TYPEintAn integer constant indicating the type of this member. Can take on one of the following values: -* -* YesNo
MEMBER_GUIDstringThe guid of this memberNoNo
MEMBER_CAPTIONstringA label or caption associated with the member. Used primarily for display purposes. If a caption does not exist, MEMBER_NAME is returned.NoNo
CHILDREN_CARDINALITYintThe number of childrend for this memberNoNo
PARENT_LEVELintThe distance of the member's parent from the root level of the hierarchy. The root level is zero (0).NoNo
DESCRIPTIONstringThis column always returns a NULL value. This column exists for backwards compatibilityNoNo
EXPRESSIONstringThe expression for calculations, if the member is of type MDMEMBER_TYPE_FORMULA.NoNo
MEMBER_KEYstringThe value of the member's key column. Returns NULL if the member has a composite key.NoNo
-* @method discoverMDMembers -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_MEMBERS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_MEMBERS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDMembers: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_MEMBERS - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_PROPERTIES schema rowset. -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the database.YesNo
SCHEMA_NAMEstringThe name of the schema to which this property belongs. NULL if the provider does not support schemas.YesYes
CUBE_NAMEstringThe name of the cube.YesYes
DIMENSION_UNIQUE_NAMEstringThe unique name of the dimension. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
HIERARCHY_UNIQUE_NAMEstringThe unique name of the hierarchy. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
LEVEL_UNIQUE_NAMEstringThe unique name of the level to which this property belongs. If the provider does not support named levels, it should return the DIMENSION_UNIQUE_NAME value for this field. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
MEMBER_UNIQUE_NAMEstringThe unique name of the member to which the property belongs. Used for data stores that do not support named levels or have properties on a member-by-member basis. If the property applies to all members in a level, this column is NULL. For providers that generate unique names by qualification, each component of this name is delimited.YesYes
PROPERTY_TYPEintA bitmap that specifies the type of the property: -*
-*
MDPROP_MEMBER (1)
identifies a property of a member. This property can be used in the DIMENSION PROPERTIES clause of the SELECT statement.
-*
MDPROP_CELL (2)
identifies a property of a cell. This property can be used in the CELL PROPERTIES clause that occurs at the end of the SELECT statement.
-*
MDPROP_SYSTEM (4)
identifies an internal property.
-*
MDPROP_BLOB (8)
identifies a property which contains a binary large object (blob).
-*
-*
YesYes
PROPERTY_NAMEstringThe name of the property. If the key for the property is the same as the name for the property, PROPERTY_NAME will be blank.YesYes
PROPERTY_CAPTIONstringA label or caption associated with the property, used primarily for display purposes. Returns PROPERTY_NAME if a caption does not exist.NoYes
DATA_TYPEintThe data type of the property.NoYes
CHARACTER_MAXIMUM_LENGTHintThe maximum possible length of the property, if it is a character, binary, or bit type. Zero indicates there is no defined maximum length. Returns NULL for all other data types.NoYes
CHARACTER_OCTET_LENGTHintThe maximum possible length (in bytes) of the property, if it is a character or binary type. Zero indicates there is no defined maximum length. Returns NULL for all other data types.NoYes
NUMERIC_PRECISIONintThe maximum precision of the property, if it is a numeric data type. Returns NULL for all other data types.NoYes
NUMERIC_SCALEintThe number of digits to the right of the decimal point, if it is a DBTYPE_NUMERIC or DBTYPE_DECIMAL type. Returns NULL for all other data types.NoYes
DESCRIPTIONstringA human readable description of the property. NULL if no description exists.NoYes
PROPERTY_CONTENT_TYPEintThe type of the property. Can be one of the following enumerations: -* YesYes
SQL_COLUMN_NAMEstringThe name of the property used in SQL queries from the cube dimension or database dDimension.NoYes
LANGUAGEintThe translation expressed as an LCID. Only valid for property translations.NoYes
PROPERTY_ORIGINintIdentifies the type of hierarchy that the property applies to:YesYes
PROPERTY_ATTRIBUTE_HIERARCHY_NAMEstringThe name of the attribute hierarchy sourcing this property.NoYes
PROPERTY_CARDINALITYstringThe cardinality of the property. Possible values include the following strings: ONE or MANYNoYes
MIME_TYPEstringThe mime type for binary large objects (BLOBs).NoYes
PROPERTY_IS_VISIBLEbooleanA Boolean that indicates whether the property is visible. TRUE if the property is visible; otherwise, FALSE.NoYes
-* @method discoverMDProperties -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_PROPERTIES request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_PROPERTIES schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDProperties: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_PROPERTIES - }, true); - return this.discover(request); - }, -/** -* Invokes the discover() method using -* as value for the requestType, -* and retrieves the MDSCHEMA_SETS schema rowset. -* ...todo... -* The rowset has the following columns: -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
Column NameTypeDescriptionRestrictionNullable
CATALOG_NAMEstringThe name of the catalog to which this set belongs.YesNo
SCHEMA_NAMEstringThe name of the schema to which this property belongs. NULL if the provider does not support schemas.YesYes
CUBE_NAMEstringThe name of the cube to which the set belongs. This column always contains a value and can never be null.YesNo
SET_NAMEstringThe name of the set.YesNo
SCOPEstringThe scope of the set.YesNo
DESCRIPTIONstringNoYes
EXPRESSIONstringThe expression for this set.NoNo
DIMENSIONSstringA comma separated list of dimensions used by this set.NoYes
-* @method discoverMDSets -* @param {Object} options An object whose properties convey the options for the XML/A a MDSCHEMA_SETS request. -* @return {Xmla.Rowset} The result of the invoking the XML/A Discover method. For synchronous requests, an instance of a Xmla.Rowset that represents the MDSCHEMA_SETS schema rowset. For an asynchronous request, the return value is not defined: you should add a listener (see: addListener()) and listen for the success (see: EVENT_SUCCESS) or discoversuccess (see: EVENT_DISCOVER_SUCCESS) events. -*/ - discoverMDSets: function(options){ - var request = _applyProps(options, { - requestType: Xmla.MDSCHEMA_SETS - }, true); - return this.discover(request); + return null; } -}; - -function _getComplexType(node, name){ - var types = _getElementsByTagNameNS(node, _xmlnsSchema, _xmlnsSchemaPrefix, "complexType"), - numTypes = types.length, - type, i - ; - for (i = 0; i < numTypes; i++){ - type = types[i]; - if (_getAttribute(type, "name")===name) return type; + + /** + *

+ * This class implements an XML/A Rowset object. + *

+ *

+ * You do not need to instantiate objects of this class yourself. + * Rather, the Xmla class will instantiate this class to convey the result of any of the various discoverXXX() methods + * (see discover()). + * In addition, this class is also used to instantiate a Resultset for the + * execute() method in case the + * Format property is set to Tabular + * (see OPTION_FORMAT and OPTION_FORMAT_TABULAR). + * The request() method itself will also return an instance of this class in case the method is used to do a + * Discover request, or in case it is used to do a Execute request and the Format property is set to Tabular. + *

+ *

+ * An instance of the Xmla.Rowset class is returned immediately as return value from the disoverXXX() or execute() method when doing a synchronous request. + * In addition, the rowset is available in the eventdata passed to any registered listeners + * (see addListener()). + * Note that for asynchronous requests, the only way to obtain the returned Rowset instance is through the listeners. + *

+ * + * @class Xmla.Rowset + * @constructor + * @param {DOMDocument} node The responseXML result returned by server in response to a Discover request. + * @param {string} requestTtype The requestType identifying the particular schema rowset to construct. This facilitates implementing field getters for a few complex types. + * @param {Xmla} xmla The Xmla instance that created this Rowset. This is mainly used to allow the Rowset to access the options passed to the Xmla constructor. + */ + Xmla.Rowset = function (node, requestType, xmla){ + if (typeof(node) === "string"){ + node = _xjs(node); + } + this._node = node; + this._type = requestType; + this._xmla = xmla; + this._initData(); + return this; + }; + + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_UNKNOWN + * @static + * @final + * @type int + * @default 0 + */ + Xmla.Rowset.MD_DIMTYPE_UNKNOWN = 0; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_TIME + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Rowset.MD_DIMTYPE_TIME = 1; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_MEASURE + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Rowset.MD_DIMTYPE_MEASURE = 2; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_OTHER + * @static + * @final + * @type int + * @default 3 + */ + Xmla.Rowset.MD_DIMTYPE_OTHER = 3; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_QUANTITATIVE + * @static + * @final + * @type int + * @default 5 + */ + Xmla.Rowset.MD_DIMTYPE_QUANTITATIVE = 5; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_ACCOUNTS + * @static + * @final + * @type int + * @default 6 + */ + Xmla.Rowset.MD_DIMTYPE_ACCOUNTS = 6; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_CUSTOMERS + * @static + * @final + * @type int + * @default 7 + */ + Xmla.Rowset.MD_DIMTYPE_CUSTOMERS = 7; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_PRODUCTS + * @static + * @final + * @type int + * @default 8 + */ + Xmla.Rowset.MD_DIMTYPE_PRODUCTS = 8; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_SCENARIO + * @static + * @final + * @type int + * @default 9 + */ + Xmla.Rowset.MD_DIMTYPE_SCENARIO = 9; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_UTILIY + * @static + * @final + * @type int + * @default 10 + */ + Xmla.Rowset.MD_DIMTYPE_UTILIY = 10; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_CURRENCY + * @static + * @final + * @type int + * @default 11 + */ + Xmla.Rowset.MD_DIMTYPE_CURRENCY = 11; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_RATES + * @static + * @final + * @type int + * @default 12 + */ + Xmla.Rowset.MD_DIMTYPE_RATES = 12; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_CHANNEL + * @static + * @final + * @type int + * @default 13 + */ + Xmla.Rowset.MD_DIMTYPE_CHANNEL = 13; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_PROMOTION + * @static + * @final + * @type int + * @default 14 + */ + Xmla.Rowset.MD_DIMTYPE_PROMOTION = 14; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_ORGANIZATION + * @static + * @final + * @type int + * @default 15 + */ + Xmla.Rowset.MD_DIMTYPE_ORGANIZATION = 15; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_BILL_OF_MATERIALS + * @static + * @final + * @type int + * @default 16 + */ + Xmla.Rowset.MD_DIMTYPE_BILL_OF_MATERIALS = 16; + /** + * A possible value for the DIMENSION_TYPE column that appears in the + * MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. + * + * @property MD_DIMTYPE_GEOGRAPHY + * @static + * @final + * @type int + * @default 17 + */ + Xmla.Rowset.MD_DIMTYPE_GEOGRAPHY = 17; + + /** + * A possible value for the STRUCTURE column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * @property MD_STRUCTURE_FULLYBALANCED + * @static + * @final + * @type int + * @default 0 + */ + Xmla.Rowset.MD_STRUCTURE_FULLYBALANCED = 0; + /** + * A possible value for the STRUCTURE column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * @property MD_STRUCTURE_RAGGEDBALANCED + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Rowset.MD_STRUCTURE_RAGGEDBALANCED = 1; + /** + * A possible value for the STRUCTURE column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * @property MD_STRUCTURE_UNBALANCED + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Rowset.MD_STRUCTURE_UNBALANCED = 2; + /** + * A possible value for the STRUCTURE column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * @property MD_STRUCTURE_NETWORK + * @static + * @final + * @type int + * @default 3 + */ + Xmla.Rowset.MD_STRUCTURE_NETWORK = 3; + + /** + * A bitmap value for the HIERARCHY_ORIGIN column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * Identifies user defined hierarchies. + * @property MD_USER_DEFINED + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Rowset.MD_USER_DEFINED = 1 + /** + * A bitmap value for the HIERARCHY_ORIGIN column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * identifies attribute hierarchies. + * @property MD_SYSTEM_ENABLED + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Rowset.MD_SYSTEM_ENABLED = 2 + /** + * A bitmap value for the HIERARCHY_ORIGIN column of the + * MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. + * identifies attributes with no attribute hierarchies. + * @property MD_SYSTEM_INTERNAL + * @static + * @final + * @type int + * @default 4 + */ + Xmla.Rowset.MD_SYSTEM_INTERNAL = 4 + + /** + * A possible value for the MEMBER_TYPE column of the + * MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), + * indicating a regular member. + * @property MDMEMBER_TYPE_REGULAR + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Rowset.MDMEMBER_TYPE_REGULAR = 1; + /** + * A possible value for the MEMBER_TYPE column of the + * MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), + * indicating an all member. + * @property MDMEMBER_TYPE_ALL + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Rowset.MDMEMBER_TYPE_ALL = 2; + /** + * A possible value for the MEMBER_TYPE column of the + * MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), + * indicating a formula member. + * @property MDMEMBER_TYPE_FORMULA + * @static + * @final + * @type int + * @default 3 + */ + Xmla.Rowset.MDMEMBER_TYPE_FORMULA = 3; + /** + * A possible value for the MEMBER_TYPE column of the + * MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), + * indicating a measure member. + * @property MDMEMBER_TYPE_MEASURE + * @static + * @final + * @type int + * @default 4 + */ + Xmla.Rowset.MDMEMBER_TYPE_MEASURE = 4; + /** + * A possible value for the MEMBER_TYPE column of the + * MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), + * indicating a member of unknown type + * @property MDMEMBER_TYPE_UNKNOWN + * @static + * @final + * @type int + * @default 0 + */ + Xmla.Rowset.MDMEMBER_TYPE_UNKNOWN = 0; + + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from SUM. + * @property MDMEASURE_AGGR_SUM + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Rowset.MDMEASURE_AGGR_SUM = 1; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from COUNT. + * @property MDMEASURE_AGGR_COUNT + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Rowset.MDMEASURE_AGGR_COUNT = 2; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from MIN. + * @property MDMEASURE_AGGR_MIN + * @static + * @final + * @type int + * @default 3 + */ + Xmla.Rowset.MDMEASURE_AGGR_MIN = 3; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from MAX. + * @property MDMEASURE_AGGR_MAX + * @static + * @final + * @type int + * @default 4 + */ + Xmla.Rowset.MDMEASURE_AGGR_MAX = 4; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from AVG. + * @property MDMEASURE_AGGR_AVG + * @static + * @final + * @type int + * @default 5 + */ + Xmla.Rowset.MDMEASURE_AGGR_AVG = 5; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from VAR. + * @property MDMEASURE_AGGR_VAR + * @static + * @final + * @type int + * @default 6 + */ + Xmla.Rowset.MDMEASURE_AGGR_VAR = 6; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from STDEV. + * @property MDMEASURE_AGGR_STD + * @static + * @final + * @type int + * @default 7 + */ + Xmla.Rowset.MDMEASURE_AGGR_STD = 7; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from DISTINCT COUNT. + * @property MDMEASURE_AGGR_DST + * @static + * @final + * @type int + * @default 8 + */ + Xmla.Rowset.MDMEASURE_AGGR_DST = 8; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from NONE. + * @property MDMEASURE_AGGR_NONE + * @static + * @final + * @type int + * @default 9 + */ + Xmla.Rowset.MDMEASURE_AGGR_NONE = 9; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from AVERAGEOFCHILDREN. + * @property MDMEASURE_AGGR_AVGCHILDREN + * @static + * @final + * @type int + * @default 10 + */ + Xmla.Rowset.MDMEASURE_AGGR_AVGCHILDREN = 10; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from FIRSTCHILD. + * @property MDMEASURE_AGGR_FIRSTCHILD + * @static + * @final + * @type int + * @default 11 + */ + Xmla.Rowset.MDMEASURE_AGGR_FIRSTCHILD = 11; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from LASTCHILD. + * @property MDMEASURE_AGGR_LASTCHILD + * @static + * @final + * @type int + * @default 12 + */ + Xmla.Rowset.MDMEASURE_AGGR_LASTCHILD = 12; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from FIRSTNONEMPTY. + * @property MDMEASURE_AGGR_FIRSTNONEMPTY + * @static + * @final + * @type int + * @default 13 + */ + Xmla.Rowset.MDMEASURE_AGGR_FIRSTNONEMPTY = 13; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from LASTNONEMPTY. + * @property MDMEASURE_AGGR_LASTNONEMPTY + * @static + * @final + * @type int + * @default 14 + */ + Xmla.Rowset.MDMEASURE_AGGR_LASTNONEMPTY = 14; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure aggregates from BYACCOUNT. + * @property MDMEASURE_AGGR_BYACCOUNT + * @static + * @final + * @type int + * @default 15 + */ + Xmla.Rowset.MDMEASURE_AGGR_BYACCOUNT = 15; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure was derived from a formula that was not any single function above. + * @property MDMEASURE_AGGR_CALCULATED + * @static + * @final + * @type int + * @default 127 + */ + Xmla.Rowset.MDMEASURE_AGGR_CALCULATED = 127; + /** + * A possible value for the MEASURE_AGGREGATOR column of the + * MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), + * identifies that the measure was derived from an unknown aggregation function or formula. + * @property MDMEASURE_AGGR_UNKNOWN + * @static + * @final + * @type int + * @default 0 + */ + Xmla.Rowset.MDMEASURE_AGGR_UNKNOWN = 0; + + /** + * Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. + * see: https://msdn.microsoft.com/en-us/library/ms126309.aspx + * Identifies a property of a member. + * If set it means this property can be used in the DIMENSION PROPERTIES clause of the SELECT statement. + * @property MDPROP_MEMBER + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Rowset.MDPROP_MEMBER = 1; + /** + * Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. + * see: https://msdn.microsoft.com/en-us/library/ms126309.aspx + * Identifies a property of a cell. + * If set, it means this property can be used in the CELL PROPERTIES clause that occurs at the end of the SELECT statement. + * @property MDPROP_CELL + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Rowset.MDPROP_CELL = 2; + /** + * Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. + * see: https://msdn.microsoft.com/en-us/library/ms126309.aspx + * Identifies an internal property. + * @property MDPROP_SYSTEM + * @static + * @final + * @type int + * @default 4 + */ + Xmla.Rowset.MDPROP_SYSTEM = 4; + /** + * Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. + * see: https://msdn.microsoft.com/en-us/library/ms126309.aspx + * Identifies an internal property. + * @property MDPROP_BLOB + * @static + * @final + * @type int + * @default 8 + */ + Xmla.Rowset.MDPROP_BLOB = 8; + + Xmla.Rowset.KEYS = {}; + Xmla.Rowset.KEYS[Xmla.DBSCHEMA_CATALOGS] = ["CATALOG_NAME"]; + Xmla.Rowset.KEYS[Xmla.DBSCHEMA_COLUMNS] = ["TABLE_CATALOG", "TABLE_SCHEMA", "TABLE_NAME", "COLUMN_NAME"]; + Xmla.Rowset.KEYS[Xmla.DBSCHEMA_PROVIDER_TYPES] = ["TYPE_NAME"]; + Xmla.Rowset.KEYS[Xmla.DBSCHEMA_SCHEMATA] = ["CATALOG_NAME", "SCHEMA_NAME"]; + Xmla.Rowset.KEYS[Xmla.DBSCHEMA_TABLES] = ["TABLE_CATALOG", "TABLE_SCHEMA", "TABLE_NAME"]; + Xmla.Rowset.KEYS[Xmla.DBSCHEMA_TABLES_INFO] = ["TABLE_CATALOG", "TABLE_SCHEMA", "TABLE_NAME"]; + Xmla.Rowset.KEYS[Xmla.DISCOVER_DATASOURCES] = ["DataSourceName"]; + Xmla.Rowset.KEYS[Xmla.DISCOVER_ENUMERATORS] = ["EnumName", "ElementName"]; + Xmla.Rowset.KEYS[Xmla.DISCOVER_KEYWORDS] = ["Keyword"]; + Xmla.Rowset.KEYS[Xmla.DISCOVER_LITERALS] = ["LiteralName"]; + Xmla.Rowset.KEYS[Xmla.DISCOVER_PROPERTIES] = ["PropertyName"]; + Xmla.Rowset.KEYS[Xmla.DISCOVER_SCHEMA_ROWSETS] = ["SchemaName"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_ACTIONS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "ACTION_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_CUBES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_DIMENSIONS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_FUNCTIONS] = ["FUNCTION_NAME", "PARAMETER_LIST"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_HIERARCHIES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_LEVELS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME", "LEVEL_UNIQUE_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_MEASURES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "MEASURE_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_MEMBERS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME", "LEVEL_UNIQUE_NAME", "MEMBER_UNIQUE_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_PROPERTIES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME", "LEVEL_UNIQUE_NAME", "MEMBER_UNIQUE_NAME", "PROPERTY_NAME"]; + Xmla.Rowset.KEYS[Xmla.MDSCHEMA_SETS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "SET_NAME"]; + + + function _boolConverter(val){ + return val==="true"?true:false; } - return null; -} - -/** -*

-* This class implements an XML/A Rowset object. -*

-*

-* You do not need to instantiate objects of this class yourself. -* Rather, the Xmla class will instantiate this class to convey the result of any of the various discoverXXX() methods -* (see discover()). -* In addition, this class is also used to instantiate a Resultset for the -* execute() method in case the -* Format property is set to Tabular -* (see OPTION_FORMAT and OPTION_FORMAT_TABULAR). -* The request() method itself will also return an instance of this class in case the method is used to do a -* Discover request, or in case it is used to do a Execute request and the Format property is set to Tabular. -*

-*

-* An instance of the Xmla.Rowset class is returned immediately as return value from the disoverXXX() or execute() method when doing a synchronous request. -* In addition, the rowset is available in the eventdata passed to any registered listeners -* (see addListener()). -* Note that for asynchronous requests, the only way to obtain the returned Rowset instance is through the listeners. -*

-* -* @class Xmla.Rowset -* @constructor -* @param {DOMDocument} node The responseXML result returned by server in response to a Discover request. -* @param {string} requestTtype The requestType identifying the particular schema rowset to construct. This facilitates implementing field getters for a few complex types. -* @param {Xmla} xmla The Xmla instance that created this Rowset. This is mainly used to allow the Rowset to access the options passed to the Xmla constructor. -*/ -Xmla.Rowset = function (node, requestType, xmla){ - if (typeof(node) === "string"){ - node = _xjs(node); + _boolConverter.jsType = "boolean"; + + function _intConverter(val){ + return parseInt(val, 10); } - this._node = node; - this._type = requestType; - this._xmla = xmla; - this._initData(); - return this; -}; - -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_UNKNOWN -* @static -* @final -* @type int -* @default 0 -*/ -Xmla.Rowset.MD_DIMTYPE_UNKNOWN = 0; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_TIME -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Rowset.MD_DIMTYPE_TIME = 1; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_MEASURE -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Rowset.MD_DIMTYPE_MEASURE = 2; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_OTHER -* @static -* @final -* @type int -* @default 3 -*/ -Xmla.Rowset.MD_DIMTYPE_OTHER = 3; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_QUANTITATIVE -* @static -* @final -* @type int -* @default 5 -*/ -Xmla.Rowset.MD_DIMTYPE_QUANTITATIVE = 5; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_ACCOUNTS -* @static -* @final -* @type int -* @default 6 -*/ -Xmla.Rowset.MD_DIMTYPE_ACCOUNTS = 6; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_CUSTOMERS -* @static -* @final -* @type int -* @default 7 -*/ -Xmla.Rowset.MD_DIMTYPE_CUSTOMERS = 7; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_PRODUCTS -* @static -* @final -* @type int -* @default 8 -*/ -Xmla.Rowset.MD_DIMTYPE_PRODUCTS = 8; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_SCENARIO -* @static -* @final -* @type int -* @default 9 -*/ -Xmla.Rowset.MD_DIMTYPE_SCENARIO = 9; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_UTILIY -* @static -* @final -* @type int -* @default 10 -*/ -Xmla.Rowset.MD_DIMTYPE_UTILIY = 10; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_CURRENCY -* @static -* @final -* @type int -* @default 11 -*/ -Xmla.Rowset.MD_DIMTYPE_CURRENCY = 11; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_RATES -* @static -* @final -* @type int -* @default 12 -*/ -Xmla.Rowset.MD_DIMTYPE_RATES = 12; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_CHANNEL -* @static -* @final -* @type int -* @default 13 -*/ -Xmla.Rowset.MD_DIMTYPE_CHANNEL = 13; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_PROMOTION -* @static -* @final -* @type int -* @default 14 -*/ -Xmla.Rowset.MD_DIMTYPE_PROMOTION = 14; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_ORGANIZATION -* @static -* @final -* @type int -* @default 15 -*/ -Xmla.Rowset.MD_DIMTYPE_ORGANIZATION = 15; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_BILL_OF_MATERIALS -* @static -* @final -* @type int -* @default 16 -*/ -Xmla.Rowset.MD_DIMTYPE_BILL_OF_MATERIALS = 16; -/** -* A possible value for the DIMENSION_TYPE column that appears in the -* MDSCHEMA_DIMENSIONS (See: discoverMDDimensions()) and -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowsets. -* -* @property MD_DIMTYPE_GEOGRAPHY -* @static -* @final -* @type int -* @default 17 -*/ -Xmla.Rowset.MD_DIMTYPE_GEOGRAPHY = 17; - -/** -* A possible value for the STRUCTURE column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* @property MD_STRUCTURE_FULLYBALANCED -* @static -* @final -* @type int -* @default 0 -*/ -Xmla.Rowset.MD_STRUCTURE_FULLYBALANCED = 0; -/** -* A possible value for the STRUCTURE column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* @property MD_STRUCTURE_RAGGEDBALANCED -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Rowset.MD_STRUCTURE_RAGGEDBALANCED = 1; -/** -* A possible value for the STRUCTURE column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* @property MD_STRUCTURE_UNBALANCED -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Rowset.MD_STRUCTURE_UNBALANCED = 2; -/** -* A possible value for the STRUCTURE column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* @property MD_STRUCTURE_NETWORK -* @static -* @final -* @type int -* @default 3 -*/ -Xmla.Rowset.MD_STRUCTURE_NETWORK = 3; - -/** -* A bitmap value for the HIERARCHY_ORIGIN column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* Identifies user defined hierarchies. -* @property MD_USER_DEFINED -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Rowset.MD_USER_DEFINED = 1 -/** -* A bitmap value for the HIERARCHY_ORIGIN column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* identifies attribute hierarchies. -* @property MD_SYSTEM_ENABLED -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Rowset.MD_SYSTEM_ENABLED = 2 -/** -* A bitmap value for the HIERARCHY_ORIGIN column of the -* MDSCHEMA_HIERARCHIES (See: discoverMDHierarchies())rowset. -* identifies attributes with no attribute hierarchies. -* @property MD_SYSTEM_INTERNAL -* @static -* @final -* @type int -* @default 4 -*/ -Xmla.Rowset.MD_SYSTEM_INTERNAL = 4 - -/** -* A possible value for the MEMBER_TYPE column of the -* MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), -* indicating a regular member. -* @property MDMEMBER_TYPE_REGULAR -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Rowset.MDMEMBER_TYPE_REGULAR = 1; -/** -* A possible value for the MEMBER_TYPE column of the -* MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), -* indicating an all member. -* @property MDMEMBER_TYPE_ALL -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Rowset.MDMEMBER_TYPE_ALL = 2; -/** -* A possible value for the MEMBER_TYPE column of the -* MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), -* indicating a formula member. -* @property MDMEMBER_TYPE_FORMULA -* @static -* @final -* @type int -* @default 3 -*/ -Xmla.Rowset.MDMEMBER_TYPE_FORMULA = 3; -/** -* A possible value for the MEMBER_TYPE column of the -* MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), -* indicating a measure member. -* @property MDMEMBER_TYPE_MEASURE -* @static -* @final -* @type int -* @default 4 -*/ -Xmla.Rowset.MDMEMBER_TYPE_MEASURE = 4; -/** -* A possible value for the MEMBER_TYPE column of the -* MDSCHEMA_MEMBERS rowset (see: discoverMDMembers()), -* indicating a member of unknown type -* @property MDMEMBER_TYPE_UNKNOWN -* @static -* @final -* @type int -* @default 0 -*/ -Xmla.Rowset.MDMEMBER_TYPE_UNKNOWN = 0; - -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from SUM. -* @property MDMEASURE_AGGR_SUM -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Rowset.MDMEASURE_AGGR_SUM = 1; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from COUNT. -* @property MDMEASURE_AGGR_COUNT -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Rowset.MDMEASURE_AGGR_COUNT = 2; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from MIN. -* @property MDMEASURE_AGGR_MIN -* @static -* @final -* @type int -* @default 3 -*/ -Xmla.Rowset.MDMEASURE_AGGR_MIN = 3; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from MAX. -* @property MDMEASURE_AGGR_MAX -* @static -* @final -* @type int -* @default 4 -*/ -Xmla.Rowset.MDMEASURE_AGGR_MAX = 4; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from AVG. -* @property MDMEASURE_AGGR_AVG -* @static -* @final -* @type int -* @default 5 -*/ -Xmla.Rowset.MDMEASURE_AGGR_AVG = 5; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from VAR. -* @property MDMEASURE_AGGR_VAR -* @static -* @final -* @type int -* @default 6 -*/ -Xmla.Rowset.MDMEASURE_AGGR_VAR = 6; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from STDEV. -* @property MDMEASURE_AGGR_STD -* @static -* @final -* @type int -* @default 7 -*/ -Xmla.Rowset.MDMEASURE_AGGR_STD = 7; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from DISTINCT COUNT. -* @property MDMEASURE_AGGR_DST -* @static -* @final -* @type int -* @default 8 -*/ -Xmla.Rowset.MDMEASURE_AGGR_DST = 8; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from NONE. -* @property MDMEASURE_AGGR_NONE -* @static -* @final -* @type int -* @default 9 -*/ -Xmla.Rowset.MDMEASURE_AGGR_NONE = 9; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from AVERAGEOFCHILDREN. -* @property MDMEASURE_AGGR_AVGCHILDREN -* @static -* @final -* @type int -* @default 10 -*/ -Xmla.Rowset.MDMEASURE_AGGR_AVGCHILDREN = 10; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from FIRSTCHILD. -* @property MDMEASURE_AGGR_FIRSTCHILD -* @static -* @final -* @type int -* @default 11 -*/ -Xmla.Rowset.MDMEASURE_AGGR_FIRSTCHILD = 11; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from LASTCHILD. -* @property MDMEASURE_AGGR_LASTCHILD -* @static -* @final -* @type int -* @default 12 -*/ -Xmla.Rowset.MDMEASURE_AGGR_LASTCHILD = 12; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from FIRSTNONEMPTY. -* @property MDMEASURE_AGGR_FIRSTNONEMPTY -* @static -* @final -* @type int -* @default 13 -*/ -Xmla.Rowset.MDMEASURE_AGGR_FIRSTNONEMPTY = 13; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from LASTNONEMPTY. -* @property MDMEASURE_AGGR_LASTNONEMPTY -* @static -* @final -* @type int -* @default 14 -*/ -Xmla.Rowset.MDMEASURE_AGGR_LASTNONEMPTY = 14; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure aggregates from BYACCOUNT. -* @property MDMEASURE_AGGR_BYACCOUNT -* @static -* @final -* @type int -* @default 15 -*/ -Xmla.Rowset.MDMEASURE_AGGR_BYACCOUNT = 15; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure was derived from a formula that was not any single function above. -* @property MDMEASURE_AGGR_CALCULATED -* @static -* @final -* @type int -* @default 127 -*/ -Xmla.Rowset.MDMEASURE_AGGR_CALCULATED = 127; -/** -* A possible value for the MEASURE_AGGREGATOR column of the -* MDSCHEMA_MEASURES rowset (see: discoverMDMeasures()), -* identifies that the measure was derived from an unknown aggregation function or formula. -* @property MDMEASURE_AGGR_UNKNOWN -* @static -* @final -* @type int -* @default 0 -*/ -Xmla.Rowset.MDMEASURE_AGGR_UNKNOWN = 0; - -/** -* Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. -* see: https://msdn.microsoft.com/en-us/library/ms126309.aspx -* Identifies a property of a member. -* If set it means this property can be used in the DIMENSION PROPERTIES clause of the SELECT statement. -* @property MDPROP_MEMBER -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Rowset.MDPROP_MEMBER = 1; -/** -* Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. -* see: https://msdn.microsoft.com/en-us/library/ms126309.aspx -* Identifies a property of a cell. -* If set, it means this property can be used in the CELL PROPERTIES clause that occurs at the end of the SELECT statement. -* @property MDPROP_CELL -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Rowset.MDPROP_CELL = 2; -/** -* Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. -* see: https://msdn.microsoft.com/en-us/library/ms126309.aspx -* Identifies an internal property. -* @property MDPROP_SYSTEM -* @static -* @final -* @type int -* @default 4 -*/ -Xmla.Rowset.MDPROP_SYSTEM = 4; -/** -* Field in the bitmap value of PROPERTY_TYPE column of the MDSCHEMA_PROPERTIES rowset. -* see: https://msdn.microsoft.com/en-us/library/ms126309.aspx -* Identifies an internal property. -* @property MDPROP_BLOB -* @static -* @final -* @type int -* @default 8 -*/ -Xmla.Rowset.MDPROP_BLOB = 8; - -Xmla.Rowset.KEYS = {}; -Xmla.Rowset.KEYS[Xmla.DBSCHEMA_CATALOGS] = ["CATALOG_NAME"]; -Xmla.Rowset.KEYS[Xmla.DBSCHEMA_COLUMNS] = ["TABLE_CATALOG", "TABLE_SCHEMA", "TABLE_NAME", "COLUMN_NAME"]; -Xmla.Rowset.KEYS[Xmla.DBSCHEMA_PROVIDER_TYPES] = ["TYPE_NAME"]; -Xmla.Rowset.KEYS[Xmla.DBSCHEMA_SCHEMATA] = ["CATALOG_NAME", "SCHEMA_NAME"]; -Xmla.Rowset.KEYS[Xmla.DBSCHEMA_TABLES] = ["TABLE_CATALOG", "TABLE_SCHEMA", "TABLE_NAME"]; -Xmla.Rowset.KEYS[Xmla.DBSCHEMA_TABLES_INFO] = ["TABLE_CATALOG", "TABLE_SCHEMA", "TABLE_NAME"]; -Xmla.Rowset.KEYS[Xmla.DISCOVER_DATASOURCES] = ["DataSourceName"]; -Xmla.Rowset.KEYS[Xmla.DISCOVER_ENUMERATORS] = ["EnumName", "ElementName"]; -Xmla.Rowset.KEYS[Xmla.DISCOVER_KEYWORDS] = ["Keyword"]; -Xmla.Rowset.KEYS[Xmla.DISCOVER_LITERALS] = ["LiteralName"]; -Xmla.Rowset.KEYS[Xmla.DISCOVER_PROPERTIES] = ["PropertyName"]; -Xmla.Rowset.KEYS[Xmla.DISCOVER_SCHEMA_ROWSETS] = ["SchemaName"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_ACTIONS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "ACTION_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_CUBES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_DIMENSIONS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_FUNCTIONS] = ["FUNCTION_NAME", "PARAMETER_LIST"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_HIERARCHIES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_LEVELS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME", "LEVEL_UNIQUE_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_MEASURES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "MEASURE_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_MEMBERS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME", "LEVEL_UNIQUE_NAME", "MEMBER_UNIQUE_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_PROPERTIES] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "DIMENSION_UNIQUE_NAME", "HIERARCHY_UNIQUE_NAME", "LEVEL_UNIQUE_NAME", "MEMBER_UNIQUE_NAME", "PROPERTY_NAME"]; -Xmla.Rowset.KEYS[Xmla.MDSCHEMA_SETS] = ["CATALOG_NAME", "SCHEMA_NAME", "CUBE_NAME", "SET_NAME"]; - - -function _boolConverter(val){ - return val==="true"?true:false; -} -_boolConverter.jsType = "boolean"; - -function _intConverter(val){ - return parseInt(val, 10); -} -_intConverter.jsType = "number"; - -function _floatConverter(val){ - return parseFloat(val, 10); -} -_floatConverter.jsType = "number"; - -function _textConverter (val){ - return val; -} -_textConverter.jsType = "string"; - -function _dateTimeConverter (val){ - return Date.parse(val); -} -_dateTimeConverter.jsType = "object"; - -function _restrictionsConverter(val){ - return val; -} -_restrictionsConverter.jsType = "object"; - -function _arrayConverter(nodes, valueConverter){ - var arr = [], - n = nodes.length, - i, node - ; - for (i = 0; i < n; i++){ - node = nodes[i]; - arr.push(valueConverter(_getElementText(node))); + _intConverter.jsType = "number"; + + function _floatConverter(val){ + return parseFloat(val, 10); } - return arr; -} -_arrayConverter.jsType = "object"; - -var _typeConverterMap = { - "xsd:boolean": _boolConverter, - "xsd:decimal": _floatConverter, - "xsd:double": _floatConverter, - "xsd:float": _floatConverter, - "xsd:int": _intConverter, - "xsd:integer": _intConverter, - "xsd:nonPositiveInteger": _intConverter, - "xsd:negativeInteger": _intConverter, - "xsd:nonNegativeInteger": _intConverter, - "xsd:positiveInteger": _intConverter, - "xsd:short": _intConverter, - "xsd:byte": _intConverter, - "xsd:long": _intConverter, - "xsd:unsignedLong": _intConverter, - "xsd:unsignedInt": _intConverter, - "xsd:unsignedShort": _intConverter, - "xsd:unsignedByte": _intConverter, - "xsd:string": _textConverter, - "xsd:dateTime": _dateTimeConverter, - "Restrictions": _restrictionsConverter -} - -function _getValueConverter(type){ - var func; - return (func = _typeConverterMap[type]) ? func : _textConverter; -} - -function _getElementValue(el) { - var txt = _getElementText(el), - type = _getAttributeNS(el, _xmlnsSchemaInstance, _xmlnsSchemaInstancePrefix, "type"), - converter + _floatConverter.jsType = "number"; + + function _textConverter (val){ + return val; + } + _textConverter.jsType = "string"; + + function _dateTimeConverter (val){ + return Date.parse(val); + } + _dateTimeConverter.jsType = "object"; + + function _restrictionsConverter(val){ + return val; + } + _restrictionsConverter.jsType = "object"; + + function _arrayConverter(nodes, valueConverter){ + var arr = [], + n = nodes.length, + i, node ; - if (type){ - converter = _typeConverterMap[type]; - if (converter){ - return converter(txt); + for (i = 0; i < n; i++){ + node = nodes[i]; + arr.push(valueConverter(_getElementText(node))); } + return arr; } - return txt; -} - -function _getterNameForColumnName(columnName){ - //sample: _getterNameForColumnName("DBLITERAL_CATALOG_NAME") returns "getDbLiteralCatalogName" - return "get" + - (/^[A-Z]+[a-z]+[A-Za-z]*$/g.test(columnName) ? columnName : - columnName.charAt(0).toUpperCase() + - columnName.substr(1).toLowerCase().replace( - /_[a-z]/g, - function(a){ - return a.charAt(1).toUpperCase(); + _arrayConverter.jsType = "object"; + + var _typeConverterMap = { + "xsd:boolean": _boolConverter, + "xsd:decimal": _floatConverter, + "xsd:double": _floatConverter, + "xsd:float": _floatConverter, + "xsd:int": _intConverter, + "xsd:integer": _intConverter, + "xsd:nonPositiveInteger": _intConverter, + "xsd:negativeInteger": _intConverter, + "xsd:nonNegativeInteger": _intConverter, + "xsd:positiveInteger": _intConverter, + "xsd:short": _intConverter, + "xsd:byte": _intConverter, + "xsd:long": _intConverter, + "xsd:unsignedLong": _intConverter, + "xsd:unsignedInt": _intConverter, + "xsd:unsignedShort": _intConverter, + "xsd:unsignedByte": _intConverter, + "xsd:string": _textConverter, + "xsd:dateTime": _dateTimeConverter, + "Restrictions": _restrictionsConverter + } + + function _getValueConverter(type){ + var func; + return (func = _typeConverterMap[type]) ? func : _textConverter; + } + + function _getElementValue(el) { + var txt = _getElementText(el), + type = _getAttributeNS(el, _xmlnsSchemaInstance, _xmlnsSchemaInstancePrefix, "type"), + converter + ; + if (type){ + converter = _typeConverterMap[type]; + if (converter){ + return converter(txt); + } + } + return txt; + } + + function _getterNameForColumnName(columnName){ + //sample: _getterNameForColumnName("DBLITERAL_CATALOG_NAME") returns "getDbLiteralCatalogName" + return "get" + + (/^[A-Z]+[a-z]+[A-Za-z]*$/g.test(columnName) ? columnName : + columnName.charAt(0).toUpperCase() + + columnName.substr(1).toLowerCase().replace( + /_[a-z]/g, + function(a){ + return a.charAt(1).toUpperCase(); + } + ) + ); + } + + Xmla.Rowset.prototype = { + _node: null, + _type: null, + _row: null, + _rows: null, + numRows: null, + fieldOrder: null, + fields: null, + _fieldCount: null, + _initData: function(){ + this._rows = _getElementsByTagNameNS(this._node, _xmlnsRowset, null, "row"); + this.numRows = this._rows? this._rows.length : 0; + this.reset(); + this.fieldOrder = []; + this.fields = {}; + this._fieldCount = 0; + var rowSchema = _getComplexType(this._node, "row"); + if (rowSchema){ + var seq = _getElementsByTagNameNS(rowSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "sequence")[0], + seqChildren = seq.childNodes, numChildren = seqChildren ? seqChildren.length : 0, seqChild, + fieldLabel, fieldName, minOccurs, maxOccurs, type, valueConverter, getter, + addFieldGetters = this._xmla.options.addFieldGetters, i, val; + for (i = 0; i < numChildren; i++){ + seqChild = seqChildren[i]; + if (seqChild.nodeType !== 1) continue; + fieldLabel = _getAttributeNS(seqChild, _xmlnsSQL, _xmlnsSQLPrefix, "field"); + fieldName = _getAttribute(seqChild, "name"); + type = _getAttribute(seqChild, "type"); //get the type from the xsd + if (type===null && this._row) { //bummer, not defined there try to get it from xsi:type in the row + val = _getElementsByTagName(this._row, fieldName); + if (val.length){ + type = _getAttributeNS( + val[0], + _xmlnsSchemaInstance, + _xmlnsSchemaInstancePrefix, + "type" + ); + } } - ) - ); -} - -Xmla.Rowset.prototype = { - _node: null, - _type: null, - _row: null, - _rows: null, - numRows: null, - fieldOrder: null, - fields: null, - _fieldCount: null, - _initData: function(){ - this._rows = _getElementsByTagNameNS(this._node, _xmlnsRowset, null, "row"); - this.numRows = this._rows? this._rows.length : 0; - this.reset(); - this.fieldOrder = []; - this.fields = {}; - this._fieldCount = 0; - var rowSchema = _getComplexType(this._node, "row"); - if (rowSchema){ - var seq = _getElementsByTagNameNS(rowSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "sequence")[0], - seqChildren = seq.childNodes, numChildren = seqChildren ? seqChildren.length : 0, seqChild, - fieldLabel, fieldName, minOccurs, maxOccurs, type, valueConverter, getter, - addFieldGetters = this._xmla.options.addFieldGetters, i, val; - for (i = 0; i < numChildren; i++){ - seqChild = seqChildren[i]; - if (seqChild.nodeType !== 1) continue; - fieldLabel = _getAttributeNS(seqChild, _xmlnsSQL, _xmlnsSQLPrefix, "field"); - fieldName = _getAttribute(seqChild, "name"); - type = _getAttribute(seqChild, "type"); //get the type from the xsd - if (type===null && this._row) { //bummer, not defined there try to get it from xsi:type in the row - val = _getElementsByTagName(this._row, fieldName); - if (val.length){ - type = _getAttributeNS( - val[0], - _xmlnsSchemaInstance, - _xmlnsSchemaInstancePrefix, - "type" - ); + if (!type && + this._type==Xmla.DISCOVER_SCHEMA_ROWSETS && + fieldName==="Restrictions" + ) type = "Restrictions"; + minOccurs = _getAttribute(seqChild, "minOccurs"); + if (minOccurs) { + minOccurs = parseInt(minOccurs, 10); } + else { + minOccurs = 1; + } + maxOccurs = _getAttribute(seqChild, "maxOccurs"); + if (maxOccurs) { + if (maxOccurs === "unbounded") { + maxOccurs = Infinity; + } + else { + minOccurs=parseInt(maxOccurs,10); + } + } + else { + maxOccurs = 1; + } + valueConverter = _getValueConverter(type); + getter = this._createFieldGetter(fieldName, valueConverter, minOccurs, maxOccurs); + if (addFieldGetters) { + this[_getterNameForColumnName(fieldName)] = getter; + } + this.fields[fieldLabel] = { + name: fieldName, + label: fieldLabel, + index: this._fieldCount++, + type: type, + jsType: valueConverter.jsType, + minOccurs: minOccurs, + maxOccurs: maxOccurs, + getter: getter + }; + this.fieldOrder.push(fieldLabel); } - if (!type && - this._type==Xmla.DISCOVER_SCHEMA_ROWSETS && - fieldName==="Restrictions" - ) type = "Restrictions"; - minOccurs = _getAttribute(seqChild, "minOccurs"); - if (minOccurs) { - minOccurs = parseInt(minOccurs, 10); - } - else { - minOccurs = 1; - } - maxOccurs = _getAttribute(seqChild, "maxOccurs"); - if (maxOccurs) { - if (maxOccurs === "unbounded") { - maxOccurs = Infinity; + } + else { + Xmla.Exception._newError( + "ERROR_PARSING_RESPONSE", + "Xmla.Rowset", + this._node + )._throw(); + } + }, + _createFieldGetter: function(fieldName, valueConverter, minOccurs, maxOccurs){ + var getter; + if (maxOccurs===1) { + if(minOccurs===1) + getter = function(){ + var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); + if (els.length) { + return valueConverter(_getElementText(els[0])); + } + else { + //SAP doesn't know how to send XML that is valid according to their XML Schema + if (!_isUnd(console.error)) { + console.error("Field \"" + fieldName + "\" is supposed to be present in the rowset but isn't. Are you running on SAP / HANA?"); + } + return null; + } + }; + else + if (minOccurs === 0) + getter = function(){ + var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); + if (els.length) { + return valueConverter(_getElementText(els[0])); + } + else { + return null; + } + }; + } + else + if(minOccurs === 1) + getter = function(){ + var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); + return _arrayConverter(els, valueConverter); + }; + else + if (minOccurs === 0) + getter = function(){ + var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); + if (els.length) { + return _arrayConverter(els, valueConverter); } else { - minOccurs=parseInt(maxOccurs,10); + return null; + } + }; + return getter; + }, + /** + * Indicates the type of rowset. In most cases, this will be identical to the requestType value that was used in the + * Discover request + * + * @method getType + * @return int One of the DISCOVER_XXX, DBSCHEMA_XXX or MDSCHEMA_XXX constants + */ + getType: function(){ + return this._type; + }, + /** + * Retrieve an array of fieldDef objects that describes the fields of the rows in this rowset. + * The position of the fieldDef objects in the array corresponds to the column order of the rowset. + * For a description of the fieldDef object, see the + * fieldDef() method. + * + * @method getFields + * @return {[fieldDef]} An (ordered) array of field definition objects. + */ + getFields: function(){ + var f = [], + i, n = this._fieldCount, + fieldOrder = this.fieldOrder + ; + for (i = 0; i < n; i++) f[i] = this.fieldDef(fieldOrder[i]); + return f; + }, + /** + * Retrieve an array of field names. + * The position of the names in the array corresponds to the column order of the rowset. + * + * @method getFieldNames + * @return {[string]} An (ordered) array of field names. + */ + getFieldNames: function(){ + var fieldNames = [], i, n = this._fieldCount; + for (i = 0; i < n; i++) fieldNames[i] = this.fieldOrder[i]; + return fieldNames; + }, + /** + * Indicates wheter the rowset can still be traversed. + * You can use this method together with the + * nextRow() method + * to drive a while loop to traverse all rows in the rowset, like so: +
+     while(rowset.hasMoreRows()){
+         ...process row...
+         rowsete.nextRow();
+     }
+        
+ * @method hasMoreRows + * @return {bool} true in case there are more rows to traverse. false if all rows have been traversed. + */ + hasMoreRows: function(){ + return this.numRows > this.rowIndex; + }, + /** + * Moves the internal row index to the next row. + * You can use this method together with the + * hasMoreRows() method + * to drive a while loop to traverse all rows in the rowset. + * + * @method nextRow + */ + nextRow: function(){ + this.rowIndex++; + this._row = this._rows[this.rowIndex]; + return this.rowIndex; + }, + /** + * This method is deprecated and may be removed in the future. + * Use nextRow() instead. + * @method next + */ + next: function(){ + return this.nextRow(); + }, + /** + *

Walks through all rows, and calls the callback function for each row.

+ * + *

The callback function gets passed an object that represents the row. + * The keys of the row object are the column names, and the values are the respective column values.

+ *

The scope for calling the callback can be passed as the second argument to this method. + * If the scope is not defined (or if it is null), the Rowset's this pointer is used instead.

+ *

You can pass additional data to the callback by passing in a third argument. This is then passed as is as second argument to the callback.

+ * + *

The eachRow method will iterate untill the callback returns false, or until all rows have been traversed. + * If the callback returns false, iteration is aborted and eachRow as a whole returns false too. + * If iteration is not aborted, then eachRow returns true.

+ * + * @method eachRow + * @param {function()} callback Function to be called for each row. + * @param {Object} scope Optional. Scope in which the callback is called. Defaults to this, that is, the Rowset. + * @param {Object} args Optional. Object that is passed as extra argument to the callback. + * @return {bool} true if all rows were itereated. If the callback returns false, iteration stops and false is returned. + */ + eachRow: function(rowCallback, scope, args){ + if (_isUnd(scope)) scope = this; + var mArgs = [null]; + if (!_isUnd(args)) { + if (!_isArr(args)) args = [args]; + mArgs = mArgs.concat(args); + } + while (this.hasMoreRows()){ + mArgs[0] = this.readAsObject(); + if (rowCallback.apply(scope, mArgs)===false) return false; + this.nextRow(); + } + return true; + }, + /** + * Gets the value of the internal row index. + * Note that no check is performed to ensure this points to a valid row: + * you should call this function only when it is safe to do so. + * This can be determined by calling hasMoreRows(). + * + * @method curr + * @return int + */ + currRow: function(){ + return this.rowIndex; + }, + /** + * Returns the number of rows in the set. + * + * @method rowCount + * @return int + */ + rowCount: function(){ + return this.numRows; + }, + /** + * Resets the internal row pointer so the resultset can be traversed again. + * + * @method reset + */ + reset: function(){ + this.rowIndex = 0; + this._row = (this.hasMoreRows()) ? this._rows[this.rowIndex] : null; + }, + /** + * Retrieves a fieldDef object by name. + * A fieldDef describes a field (column). It has the following properties: + *
+ *
label
string. This is the human readable name for this field. You should use this name for display purposes and for building restrictions. This is also the name used for matching againstt the name argument passed to the fieldDef() method.
+ *
name
string. This is the (possibly escaped) name of the field as it appears in the XML document
+ *
index
int. The ordinal position of this field. Fields are numbered starting from 0.
+ *
type
string. The name of the XML data type for the values that appear in this column
+ *
minOccurs
string. The minimal number of occurrences of a value. "0" means the field is optional.
+ *
maxOccurs
string. If this is parseable as an integer, that integer specifies the number of times a value can appear in this column. "unbounded" means there is no declared limit.
+ *
getter
function. This function is used to extract a value from the XML document for this field.
+ *
+ * @method fieldDef + * @param {string} name The name of the field to retrieve. + * @return {fieldDef} The fieldDef object that matches the argument. + */ + fieldDef: function(name){ + var field = this.fields[name]; + if (!field) + Xmla.Exception._newError( + "INVALID_FIELD", + "Xmla.Rowset.fieldDef", + name + )._throw(); + return field; + }, + /** + * Retrieves the index of a field by name. + * Field indexes start at 0. + * @method fieldIndex + * @param {string} name The name of the field for which you want to retrieve the index. + * @return {int} The ordinal position (starting at 0) of the field that matches the argument. + */ + fieldIndex: function(name){ + return this.fieldDef(name).index; + }, + /** + * Retrieves the name of a field by field Index. + * Field indexes start at 0. + * @method fieldName + * @param {string} name The name of the field for which you want to retrieve the index. + * @return {int} The ordinal position (starting at 0) of the field that matches the argument. + */ + fieldName: function(index){ + var fieldName = this.fieldOrder[index]; + if (!fieldName) + Xmla.Exception._newError( + "INVALID_FIELD", + "Xmla.Rowset.fieldDef", + index + )._throw(); + return fieldName; + }, + /** + * Retrieves a value from the current row for the field having the name specified by the argument. + * @method fieldVal + * @param {string | int} name The name or the index of the field for which you want to retrieve the value. + * @return {array|boolean|float|int|string} From the current row, the value of the field that matches the argument. + */ + fieldVal: function(name){ + if (_isNum(name)) name = this.fieldName(name); + return this.fieldDef(name).getter.call(this); + }, + /** + * Returns the number of fields in this rowset. + * @method fieldCount + * @return {int} The number of fields in this rowset. + */ + fieldCount: function(){ + return this._fieldCount; + }, + /** + * Releases references to the DomDocument passed to the Rowset constructor. + * This should facilitate automatic garbage collection by the browser. + * @method close + */ + close: function(){ + this._node = null; + this._row = null; + this._rows = null; + }, + /** + * Reads the current row and returns the result as a new array. + * This method does not advance the internal row pointer, and does not check if there is a valid row. + * This method exists mainly as a convience in case you want to use a custom way to extract data from the resultset using the + * fetchCustom() method. + * If you just want to obtain the results as arrays, see + * fetchAsArray() + * and + * fetchAllAsArray(). + * @method readAsArray + * @return {array} + */ + readAsArray: function(array){ + var fields = this.fields, fieldName, fieldDef; + if (!array) array = []; + for (fieldName in fields){ + if (fields.hasOwnProperty(fieldName)){ + fieldDef = fields[fieldName]; + array[fieldDef.index] = fieldDef.getter.call(this); + } + } + return array; + }, + /** + * Fetch all values from all fields from the current row, and return it in an array. + * The position of the values in the array corresponds to the column order of the rowset. + * The internal row pointer is also increased so the next call will read the next row. + * The method returns false when there are no more rows to traverse. + * You can use this method to drive a loop to travere all rows in the Rowset: +
+    while (rowArray = rowset.fetchAsArray()){
+        ...process array...
+    }
+    
+ * @method fetchAsArray + * @return {array} + */ + fetchAsArray: function(array){ + if (this.hasMoreRows()) { + array = this.readAsArray(array); + this.nextRow(); + } + else array = false; + return array; + }, + /** + * Reads the current row and returns the result as a new object. + * This method does not advance the internal row pointer, and does not check if there is a valid row. + * This method exists mainly as a convience in case you want to use a custom way to extract data from the resultset using the + * fetchCustom() method. + * If you just want to obtain the results as objects, see + * fetchAsObject() + * and + * fetchAllAsObject(). + * @method readAsObject + * @return {object} + */ + readAsObject: function(object){ + var fields = this.fields, fieldName, fieldDef; + if (!object) object = {}; + for (fieldName in fields) { + if (fields.hasOwnProperty(fieldName)) { + fieldDef = fields[fieldName]; + object[fieldName] = fieldDef.getter.call(this); + } + } + return object; + }, + /** + * Fetch all values from all fields from the current row, and return it in an Object literal. + * The property names of the returned object correspond to the fieldName (actually the fieldLabel), and the field value is assigned to its respective property. + * The internal row pointer is also increased so the next call will read the next row. + * The method returns false when there are no more rows to traverse. + * You can use this method to drive a loop to travere all rows in the Rowset: +
+    while (rowObject = rowset.fetchAsObject()){
+        ...process object...
+    }
+    
+ * @method fetchAsObject + * @return {Object|boolean} + */ + fetchAsObject: function(object){ + if (this.hasMoreRows()){ + object = this.readAsObject(object); + this.nextRow(); + } + else object = false; + return object; + }, + /** + * Fetch the values using a custom callback function. + * If there are rows to fetch, the custom function is called in scope of the rowset, so you can use this inside the custom function to refer to the rowset object. + * Then, the internal row pointer is increased so the next call will read the next row. + * The method returns whatever object or value is returned by the custom function, or false when there are no more rows to traverse. + * + * @method fetchCustom + * @param func {function} a custom function to extract and return the data from the current row of the xml result. + * @param args {object} an object that will be passed to the function. Useful to hold any data required in addition to the rowset itself (which can be referred to as this inside the function). + * @return {mixed|boolean} + */ + fetchCustom: function(func, args){ + var object; + if (this.hasMoreRows()){ + object = func.call(this, args); + this.nextRow(); + } + else object = false; + return object; + }, + /** + * Fetch all values from all fields from all rows, and return it as an array of arrays. + * See fetchAsArray(). + * @method fetchAllAsArray + * @param rows {array[]} OPTIONAL. An array to append the rows to. If not specified, a new array is created + * @return {array} + */ + fetchAllAsArray: function(rows){ + var row; + if (!rows) rows = []; + while((row = this.fetchAsArray())) rows.push(row); + return rows; + }, + /** + * Fetch all values from all fields from all rows, and return it as an array of objects. + * See fetchAsObject(). + * @method fetchAllAsObject + * @param rows {array[]} OPTIONAL. An array to append the rows to. If not specified, a new array is created + * @return {array} + */ + fetchAllAsObject: function(rows){ + var row; + if (!rows) rows = []; + while((row = this.fetchAsObject())) rows.push(row); + return rows; + }, + /** + * Fetch all rows using a custom function, and return the return values as an array. + * See fetchCustom(). + * @method fetchAllCustom + * @param rows {array[]} OPTIONAL. An array to append the rows to. If not specified, a new array is created + * @param func {function} a callback function to extract the fields. + * @param args {object} an object to pass data to the callback. + * @return {array} + */ + fetchAllCustom: function(rows, func, args){ + var row; + if (!rows) rows = []; + while((row = this.fetchCustom(func, args))) rows.push(row); + return rows; + }, + /** + * Fetch all row as an object, store it in nested objects according to values in the column identified by the key argument. + * This method should typically not be called directly, rather it is a helper method for mapAllAsObject(). + * + * @method mapAsObject + * @param map + * @param key + * @param row + * @return {object} a tree using column values as branch names, and storing a row or an array of rows at the leaves. + */ + mapAsObject: function(map, key, row){ + var k, v, p, i, len = key.length, last = len - 1, m = map; + for (i = 0; i < len; i++){ + k = key[i]; //get the keypart + v = row[k]; //get the value for the key part + p = m[v]; //get the property from the map for this keypart. + if (p) { + if (i === last) { //last, we need to store the row now. + if (_isArr(p)) p.push(row); //already entries here, append + else m[v] = [p, row]; //single row store here. since we need multiple rows, add an array } + else m = p; } - else { - maxOccurs = 1; - } - valueConverter = _getValueConverter(type); - getter = this._createFieldGetter(fieldName, valueConverter, minOccurs, maxOccurs); - if (addFieldGetters) { - this[_getterNameForColumnName(fieldName)] = getter; - } - this.fields[fieldLabel] = { - name: fieldName, - label: fieldLabel, - index: this._fieldCount++, - type: type, - jsType: valueConverter.jsType, - minOccurs: minOccurs, - maxOccurs: maxOccurs, - getter: getter - }; - this.fieldOrder.push(fieldLabel); + else //property didnt exist for this key yet. + if (i === last) m[v] = row; //last keypart: store the row here + else m = m[v] = {}; //more keyparts to go: add a new map for this keypart } + }, + /** + * Fetch all rows as an object, store them as proprties in an object (which acts as map). + * @method mapAllAsObject + * @param key {string|array} OPTIONAL. A column name or an array of column names that will be used to generate property names for the map. If not specified, the default key is used. If there is no default key, all column names will be used. + * @param map {object} OPTIONAL. The object that is used as map. Rows are added as properties to this map. If not specified, a new object is created + * @return {object} + */ + mapAllAsObject: function(key, map){ + if (!map) map = {}; + if (!key) key = this.getKey(); + var row; + while (row = this.fetchAsObject()) this.mapAsObject(map, key, row); + return map; + }, + + /* + * Find a key for the resultset type. + */ + getKey: function(){ + return (this._type) ? Xmla.Rowset.KEYS[this._type] : this.getFieldNames(); } - else { - Xmla.Exception._newError( - "ERROR_PARSING_RESPONSE", - "Xmla.Rowset", - this._node - )._throw(); + }; + + /** + *

+ * This class implements an XML/A multidimensional Dataset object. + *

+ *

+ * You do not need to instantiate objects of this class yourself. + * Rather, the Xmla class will instantiate this class + * to convey the result of the executeMultiDimensional method + * (see executeMultiDimensional()), + * and possibly the execute method. + * (Note that the execute() instantiates either the + * Xmla.Rowset or the Xmla.Dataset class + * depending on the value of the Format property in the options passed to the execute() method.) + *

+ *

+ * An instance of the Xmla.Dataset class may be returned immediately as return value from these methods when doing a synchronous request. + * In addition, the Xmla.Dataset object is available in the eventdata passed to any registered listeners + * (see addListener()). + *

+ * + * @class Xmla.Dataset + * @constructor + * @param {DOMDocument} doc The responseXML result returned by server in response to a Execute request. + */ + Xmla.Dataset = function(doc){ + if (typeof(doc) === "string") { + doc = _xjs(doc); } - }, - _createFieldGetter: function(fieldName, valueConverter, minOccurs, maxOccurs){ - var getter; - if (maxOccurs===1) { - if(minOccurs===1) - getter = function(){ - var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); - if (els.length) { - return valueConverter(_getElementText(els[0])); - } - else { - //SAP doesn't know how to send XML that is valid according to their XML Schema - if (!_isUnd(console.error)) { - console.error("Field \"" + fieldName + "\" is supposed to be present in the rowset but isn't. Are you running on SAP / HANA?"); - } - return null; - } - }; + this._initDataset(doc); + return this; + } + + /** + * Can be used as argument for getAxis() to get the first axis (the column axis). + * Alternatively you can simply call getColumnAxis() + * @property AXIS_COLUMNS + * @static + * @final + * @type int + * @default 0 + */ + Xmla.Dataset.AXIS_COLUMNS = 0; + /** + * Can be used as argument for getAxis() to get the second axis (the row axis). + * Alternatively you can simply call getRowAxis() + * @property AXIS_ROWS + * @static + * @final + * @type int + * @default 1 + */ + Xmla.Dataset.AXIS_ROWS = 1; + /** + * Can be used as argument for getAxis() to get the third axis (the page axis). + * Alternatively you can simply call getPageAxis() + * @property AXIS_PAGES + * @static + * @final + * @type int + * @default 2 + */ + Xmla.Dataset.AXIS_PAGES = 2; + /** + * Can be used as argument for getAxis() to get the fourth axis (the section axis). + * Alternatively you can simply call getSectionAxis() + * @property AXIS_SECTIONS + * @static + * @final + * @type int + * @default 3 + */ + Xmla.Dataset.AXIS_SECTIONS = 3; + /** + * Can be used as argument for getAxis() to get the fifth axis (the chapters axis). + * Alternatively you can simply call getChapterAxis() + * @property AXIS_CHAPTERS + * @static + * @final + * @type int + * @default 4 + */ + Xmla.Dataset.AXIS_CHAPTERS = 4; + /** + * Can be used as argument for getAxis() to get the slicer axis + * (the axis that appears in the WHERE clause of an MDX-SELECT statement). + * Alternatively you can simply call getSlicerAxis() + * @property AXIS_SLICER + * @static + * @final + * @type string + * @default SlicerAxis + */ + Xmla.Dataset.AXIS_SLICER = "SlicerAxis"; + + Xmla.Dataset.prototype = { + _root: null, + _axes: null, + _axesOrder: null, + _numAxes: null, + _slicer: null, + _cellset:null, + _initDataset: function(doc){ + this._initRoot(doc); + this.cubeName = _getElementText( + _getElementsByTagNameNS( + this._root, _xmlnsDataset, "", "CubeName" + )[0] + ); + this._initAxes(); + this._initCells(); + /* + var a, i, j, func, funcBody = "", mul; + func = "var ordinal = 0, a;" + + "\nif (arguments.length !== " + this._numAxes + ") new Xmla.Exception._newError(\"ERROR_ILLEGAL_ARGUMENT\", \"cellOrdinalForTupleIndexes\", this)._throw();" + for (a = 0, i = this._numAxes-1; i >= 0; i--, a++) { + func += "\nif (typeof(a = arguments[" + a + "])!==\"number\") new Xmla.Exception._newError(\"ERROR_ILLEGAL_ARGUMENT\", \"cellOrdinalForTupleIndexes\", this)._throw();"; + mul = 1; + for (j = i-1; j >= 0; j--) mul *= this._axesOrder[j].tupleCount(); + func += "\nordinal += a "; + if (i) func += "* " + mul + ";"; + } + func += funcBody + "\nreturn ordinal;" + this._cellset.cellOrdinalForTupleIndexes = this.cellOrdinalForTupleIndexes = new Function(func); + */ + }, + _initRoot: function(doc){ + var root = _getElementsByTagNameNS(doc, _xmlnsDataset, "", "root"); + if (root.length) this._root = root[0]; else - if (minOccurs === 0) - getter = function(){ - var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); - if (els.length) { - return valueConverter(_getElementText(els[0])); - } - else { - return null; - } - }; - } - else - if(minOccurs === 1) - getter = function(){ - var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); - return _arrayConverter(els, valueConverter); - }; - else - if (minOccurs === 0) - getter = function(){ - var els = _getElementsByTagNameNS (this._row, _xmlnsRowset, null, fieldName); - if (els.length) { - return _arrayConverter(els, valueConverter); - } + Xmla.Exception._newError( + "ERROR_PARSING_RESPONSE", + "Xmla.Dataset._initData", + doc + )._throw(); + }, + _initAxes: function(){ + var i, axis, axisNode, axisName, axisNodes, numAxisNodes, tmpAxes = {}; + + this._axes = {}; + this._axesOrder = []; + + //collect the axisInfo nodes + axisNodes = _getElementsByTagNameNS(this._root, _xmlnsDataset, "", "AxisInfo"); + numAxisNodes = axisNodes.length; + for (i = 0; i < numAxisNodes; i++) { + axisNode = axisNodes[i]; + axisName = _getAttribute(axisNode, "name"); + tmpAxes[axisName] = axisNode; + } + //collect the axis nodes + axisNodes = _getElementsByTagNameNS(this._root, _xmlnsDataset, "", "Axis"); + numAxisNodes = axisNodes.length; + for (i = 0; i < numAxisNodes; i++){ + axisNode = axisNodes[i]; + axisName = _getAttribute(axisNode, "name"); + axis = new Xmla.Dataset.Axis(this, tmpAxes[axisName], axisNode, axisName, i); + if (axisName === Xmla.Dataset.AXIS_SLICER) this._slicer = axis; else { - return null; + this._axes[axisName] = axis; + this._axesOrder.push(axis); } - }; - return getter; - }, -/** -* Indicates the type of rowset. In most cases, this will be identical to the requestType value that was used in the -* Discover request -* -* @method getType -* @return int One of the DISCOVER_XXX, DBSCHEMA_XXX or MDSCHEMA_XXX constants -*/ - getType: function(){ - return this._type; - }, -/** -* Retrieve an array of fieldDef objects that describes the fields of the rows in this rowset. -* The position of the fieldDef objects in the array corresponds to the column order of the rowset. -* For a description of the fieldDef object, see the -* fieldDef() method. -* -* @method getFields -* @return {[fieldDef]} An (ordered) array of field definition objects. -*/ - getFields: function(){ - var f = [], - i, n = this._fieldCount, - fieldOrder = this.fieldOrder - ; - for (i = 0; i < n; i++) f[i] = this.fieldDef(fieldOrder[i]); - return f; - }, -/** -* Retrieve an array of field names. -* The position of the names in the array corresponds to the column order of the rowset. -* -* @method getFieldNames -* @return {[string]} An (ordered) array of field names. -*/ - getFieldNames: function(){ - var fieldNames = [], i, n = this._fieldCount; - for (i = 0; i < n; i++) fieldNames[i] = this.fieldOrder[i]; - return fieldNames; - }, -/** -* Indicates wheter the rowset can still be traversed. -* You can use this method together with the -* nextRow() method -* to drive a while loop to traverse all rows in the rowset, like so: -
- while(rowset.hasMoreRows()){
-     ...process row...
-     rowsete.nextRow();
- }
-    
-* @method hasMoreRows -* @return {bool} true in case there are more rows to traverse. false if all rows have been traversed. -*/ - hasMoreRows: function(){ - return this.numRows > this.rowIndex; - }, -/** -* Moves the internal row index to the next row. -* You can use this method together with the -* hasMoreRows() method -* to drive a while loop to traverse all rows in the rowset. -* -* @method nextRow -*/ - nextRow: function(){ - this.rowIndex++; - this._row = this._rows[this.rowIndex]; - return this.rowIndex; - }, -/** -* This method is deprecated and may be removed in the future. -* Use nextRow() instead. -* @method next -*/ - next: function(){ - return this.nextRow(); - }, -/** -*

Walks through all rows, and calls the callback function for each row.

-* -*

The callback function gets passed an object that represents the row. -* The keys of the row object are the column names, and the values are the respective column values.

-*

The scope for calling the callback can be passed as the second argument to this method. -* If the scope is not defined (or if it is null), the Rowset's this pointer is used instead.

-*

You can pass additional data to the callback by passing in a third argument. This is then passed as is as second argument to the callback.

-* -*

The eachRow method will iterate untill the callback returns false, or until all rows have been traversed. -* If the callback returns false, iteration is aborted and eachRow as a whole returns false too. -* If iteration is not aborted, then eachRow returns true.

-* -* @method eachRow -* @param {function()} callback Function to be called for each row. -* @param {Object} scope Optional. Scope in which the callback is called. Defaults to this, that is, the Rowset. -* @param {Object} args Optional. Object that is passed as extra argument to the callback. -* @return {bool} true if all rows were itereated. If the callback returns false, iteration stops and false is returned. -*/ - eachRow: function(rowCallback, scope, args){ - if (_isUnd(scope)) scope = this; - var mArgs = [null]; - if (!_isUnd(args)) { - if (!_isArr(args)) args = [args]; - mArgs = mArgs.concat(args); - } - while (this.hasMoreRows()){ - mArgs[0] = this.readAsObject(); - if (rowCallback.apply(scope, mArgs)===false) return false; - this.nextRow(); - } - return true; - }, -/** -* Gets the value of the internal row index. -* Note that no check is performed to ensure this points to a valid row: -* you should call this function only when it is safe to do so. -* This can be determined by calling hasMoreRows(). -* -* @method curr -* @return int -*/ - currRow: function(){ - return this.rowIndex; - }, -/** -* Returns the number of rows in the set. -* -* @method rowCount -* @return int -*/ - rowCount: function(){ - return this.numRows; - }, -/** -* Resets the internal row pointer so the resultset can be traversed again. -* -* @method reset -*/ - reset: function(){ - this.rowIndex = 0; - this._row = (this.hasMoreRows()) ? this._rows[this.rowIndex] : null; - }, -/** -* Retrieves a fieldDef object by name. -* A fieldDef describes a field (column). It has the following properties: -*
-*
label
string. This is the human readable name for this field. You should use this name for display purposes and for building restrictions. This is also the name used for matching againstt the name argument passed to the fieldDef() method.
-*
name
string. This is the (possibly escaped) name of the field as it appears in the XML document
-*
index
int. The ordinal position of this field. Fields are numbered starting from 0.
-*
type
string. The name of the XML data type for the values that appear in this column
-*
minOccurs
string. The minimal number of occurrences of a value. "0" means the field is optional.
-*
maxOccurs
string. If this is parseable as an integer, that integer specifies the number of times a value can appear in this column. "unbounded" means there is no declared limit.
-*
getter
function. This function is used to extract a value from the XML document for this field.
-*
-* @method fieldDef -* @param {string} name The name of the field to retrieve. -* @return {fieldDef} The fieldDef object that matches the argument. -*/ - fieldDef: function(name){ - var field = this.fields[name]; - if (!field) - Xmla.Exception._newError( - "INVALID_FIELD", - "Xmla.Rowset.fieldDef", - name - )._throw(); - return field; - }, -/** -* Retrieves the index of a field by name. -* Field indexes start at 0. -* @method fieldIndex -* @param {string} name The name of the field for which you want to retrieve the index. -* @return {int} The ordinal position (starting at 0) of the field that matches the argument. -*/ - fieldIndex: function(name){ - return this.fieldDef(name).index; - }, -/** -* Retrieves the name of a field by field Index. -* Field indexes start at 0. -* @method fieldName -* @param {string} name The name of the field for which you want to retrieve the index. -* @return {int} The ordinal position (starting at 0) of the field that matches the argument. -*/ - fieldName: function(index){ - var fieldName = this.fieldOrder[index]; - if (!fieldName) - Xmla.Exception._newError( - "INVALID_FIELD", - "Xmla.Rowset.fieldDef", - index - )._throw(); - return fieldName; - }, -/** -* Retrieves a value from the current row for the field having the name specified by the argument. -* @method fieldVal -* @param {string | int} name The name or the index of the field for which you want to retrieve the value. -* @return {array|boolean|float|int|string} From the current row, the value of the field that matches the argument. -*/ - fieldVal: function(name){ - if (_isNum(name)) name = this.fieldName(name); - return this.fieldDef(name).getter.call(this); - }, -/** -* Returns the number of fields in this rowset. -* @method fieldCount -* @return {int} The number of fields in this rowset. -*/ - fieldCount: function(){ - return this._fieldCount; - }, -/** -* Releases references to the DomDocument passed to the Rowset constructor. -* This should facilitate automatic garbage collection by the browser. -* @method close -*/ - close: function(){ - this._node = null; - this._row = null; - this._rows = null; - }, -/** -* Reads the current row and returns the result as a new array. -* This method does not advance the internal row pointer, and does not check if there is a valid row. -* This method exists mainly as a convience in case you want to use a custom way to extract data from the resultset using the -* fetchCustom() method. -* If you just want to obtain the results as arrays, see -* fetchAsArray() -* and -* fetchAllAsArray(). -* @method readAsArray -* @return {array} -*/ - readAsArray: function(array){ - var fields = this.fields, fieldName, fieldDef; - if (!array) array = []; - for (fieldName in fields){ - if (fields.hasOwnProperty(fieldName)){ - fieldDef = fields[fieldName]; - array[fieldDef.index] = fieldDef.getter.call(this); } - } - return array; - }, -/** -* Fetch all values from all fields from the current row, and return it in an array. -* The position of the values in the array corresponds to the column order of the rowset. -* The internal row pointer is also increased so the next call will read the next row. -* The method returns false when there are no more rows to traverse. -* You can use this method to drive a loop to travere all rows in the Rowset: -
-while (rowArray = rowset.fetchAsArray()){
-    ...process array...
-}
-
-* @method fetchAsArray -* @return {array} -*/ - fetchAsArray: function(array){ - if (this.hasMoreRows()) { - array = this.readAsArray(array); - this.nextRow(); - } - else array = false; - return array; - }, -/** -* Reads the current row and returns the result as a new object. -* This method does not advance the internal row pointer, and does not check if there is a valid row. -* This method exists mainly as a convience in case you want to use a custom way to extract data from the resultset using the -* fetchCustom() method. -* If you just want to obtain the results as objects, see -* fetchAsObject() -* and -* fetchAllAsObject(). -* @method readAsObject -* @return {object} -*/ - readAsObject: function(object){ - var fields = this.fields, fieldName, fieldDef; - if (!object) object = {}; - for (fieldName in fields) { - if (fields.hasOwnProperty(fieldName)) { - fieldDef = fields[fieldName]; - object[fieldName] = fieldDef.getter.call(this); + this._numAxes = this._axesOrder.length; + }, + _initCells: function(){ + this._cellset = new Xmla.Dataset.Cellset(this); + }, + /** + * Get the number of proper axes in this Dataset. This is the number of axes that appears in the SELECT list, and excludes the slicer axis. + * @method axisCount + * @return {int} + */ + axisCount: function(){ + return this._numAxes; + }, + _getAxis: function(nameOrIndex) { + var name, axis; + switch (typeof(nameOrIndex)) { + case "number": + axis = this._axesOrder[nameOrIndex]; + break; + case "string": + axis = (name === Xmla.Dataset.AXIS_SLICER) ? this._slicer : this._axes[name]; + break; } - } - return object; - }, -/** -* Fetch all values from all fields from the current row, and return it in an Object literal. -* The property names of the returned object correspond to the fieldName (actually the fieldLabel), and the field value is assigned to its respective property. -* The internal row pointer is also increased so the next call will read the next row. -* The method returns false when there are no more rows to traverse. -* You can use this method to drive a loop to travere all rows in the Rowset: -
-while (rowObject = rowset.fetchAsObject()){
-    ...process object...
-}
-
-* @method fetchAsObject -* @return {Object|boolean} -*/ - fetchAsObject: function(object){ - if (this.hasMoreRows()){ - object = this.readAsObject(object); - this.nextRow(); - } - else object = false; - return object; - }, -/** -* Fetch the values using a custom callback function. -* If there are rows to fetch, the custom function is called in scope of the rowset, so you can use this inside the custom function to refer to the rowset object. -* Then, the internal row pointer is increased so the next call will read the next row. -* The method returns whatever object or value is returned by the custom function, or false when there are no more rows to traverse. -* -* @method fetchCustom -* @param func {function} a custom function to extract and return the data from the current row of the xml result. -* @param args {object} an object that will be passed to the function. Useful to hold any data required in addition to the rowset itself (which can be referred to as this inside the function). -* @return {mixed|boolean} -*/ - fetchCustom: function(func, args){ - var object; - if (this.hasMoreRows()){ - object = func.call(this, args); - this.nextRow(); - } - else object = false; - return object; - }, -/** -* Fetch all values from all fields from all rows, and return it as an array of arrays. -* See fetchAsArray(). -* @method fetchAllAsArray -* @param rows {array[]} OPTIONAL. An array to append the rows to. If not specified, a new array is created -* @return {array} -*/ - fetchAllAsArray: function(rows){ - var row; - if (!rows) rows = []; - while((row = this.fetchAsArray())) rows.push(row); - return rows; - }, -/** -* Fetch all values from all fields from all rows, and return it as an array of objects. -* See fetchAsObject(). -* @method fetchAllAsObject -* @param rows {array[]} OPTIONAL. An array to append the rows to. If not specified, a new array is created -* @return {array} -*/ - fetchAllAsObject: function(rows){ - var row; - if (!rows) rows = []; - while((row = this.fetchAsObject())) rows.push(row); - return rows; - }, -/** -* Fetch all rows using a custom function, and return the return values as an array. -* See fetchCustom(). -* @method fetchAllCustom -* @param rows {array[]} OPTIONAL. An array to append the rows to. If not specified, a new array is created -* @param func {function} a callback function to extract the fields. -* @param args {object} an object to pass data to the callback. -* @return {array} -*/ - fetchAllCustom: function(rows, func, args){ - var row; - if (!rows) rows = []; - while((row = this.fetchCustom(func, args))) rows.push(row); - return rows; - }, -/** -* Fetch all row as an object, store it in nested objects according to values in the column identified by the key argument. -* This method should typically not be called directly, rather it is a helper method for mapAllAsObject(). -* -* @method mapAsObject -* @param map -* @param key -* @param row -* @return {object} a tree using column values as branch names, and storing a row or an array of rows at the leaves. -*/ - mapAsObject: function(map, key, row){ - var k, v, p, i, len = key.length, last = len - 1, m = map; - for (i = 0; i < len; i++){ - k = key[i]; //get the keypart - v = row[k]; //get the value for the key part - p = m[v]; //get the property from the map for this keypart. - if (p) { - if (i === last) { //last, we need to store the row now. - if (_isArr(p)) p.push(row); //already entries here, append - else m[v] = [p, row]; //single row store here. since we need multiple rows, add an array - } - else m = p; + return axis; + }, + /** + * Get the axis specified by the argument index or name. + * If the axis does not exist, an INVALID_AXIS exception is thrown. + * To prevent an exception from being thrown, you should call the hasAxis() method to determine if the axis exists. + * Alternatively, you can call axisCount(), and use an integer argument between zero (inclusive) and axis count (exclusive). + * @method getAxis + * @param nameOrIndex {string | int} For int arguments, a value of 0 up to the number of axes. You can also use one of the AXIS_xxx constants. For string arguments, this method will match the name of the axis as it is returned in the XML/A response. These names are of the form AxisN where N is an ordinal that identifies the axis. + * @return {Xmla.Dataset.Axis} The Xmla.Dataset.Axis object that corresponds to the argument. + */ + getAxis: function(nameOrIndex){ + if (nameOrIndex === Xmla.Dataset.AXIS_SLICER) return this._slicer; + var axis = this._getAxis(nameOrIndex); + if (!axis) + Xmla.Exception._newError( + "INVALID_AXIS", + "Xmla.Dataset.getAxis", + nameOrIndex + )._throw(); + return axis; + }, + /** + * Determine if the axis specified by the argument exists. + * @method hasAxis + * @param nameOrIndex {string | int} For int arguments, a value of 0 up to the number of axes. You can also use one of the AXIS_xxx constants. For string arguments, this method will match the name of the axis as it is returned in the XML/A response. These names are of the form AxisN where N is an ordinal that identifies the axis. + * @return {boolean} true if the specified axis exists, false if it doesn't exist. + */ + hasAxis: function(nameOrIndex) { + var axis = this._getAxis(nameOrIndex); + return !_isUnd(axis); + }, + /** + * Get the Column axis. This is the first axis, and has ordinal 0. If the column axis doesn't exist, an INVALID_AXIS exception is thrown. + * To prevent an exception from being thrown, you should call the hasColumnAxis() method to determine if the axis exists. + * @method getColumnAxis + * @return {Xmla.Dataset.Axis} The column Xmla.Dataset.Axis object. + */ + getColumnAxis: function(){ + return this.getAxis(Xmla.Dataset.AXIS_COLUMNS); + }, + /** + * Determine if the column axis exists. + * @method hasColumnAxis + * @return {boolean} true if the column axis exists, false if it doesn't exist. + */ + hasColumnAxis: function(){ + return this.hasAxis(Xmla.Dataset.AXIS_COLUMNS); + }, + /** + * Get the Row axis. This is the second axis, and has ordinal 1. If the row axis doesn't exist, an INVALID_AXIS exception is thrown. + * To prevent an exception from being thrown, you should call the hasRowAxis() method to determine if the axis exists. + * @method getRowAxis + * @return {Xmla.Dataset.Axis} The row Xmla.Dataset.Axis object. + */ + getRowAxis: function(){ + return this.getAxis(Xmla.Dataset.AXIS_ROWS); + }, + /** + * Determine if the row axis exists. + * @method hasRowAxis + * @return {boolean} true if the row axis exists, false if it doesn't exist. + */ + hasRowAxis: function(){ + return this.hasAxis(Xmla.Dataset.AXIS_ROWS); + }, + /** + * Get the Page axis. This is the third axis, and has ordinal 2. If the page axis doesn't exist, an INVALID_AXIS exception is thrown. + * To prevent an exception from being thrown, you should call the hasPageAxis() method to determine if the axis exists. + * @method getPageAxis + * @return {Xmla.Dataset.Axis} The page Xmla.Dataset.Axis object. + */ + getPageAxis: function(){ + return this.getAxis(Xmla.Dataset.AXIS_PAGES); + }, + /** + * Determine if the page axis exists. + * @method hasPageAxis + * @return {boolean} true if the page axis exists, false if it doesn't exist. + */ + hasPageAxis: function(){ + return this.hasAxis(Xmla.Dataset.AXIS_PAGES); + }, + /** + * Get the Chapter axis. This is the fourth axis, and has ordinal 3. If the chapter axis doesn't exist, an INVALID_AXIS exception is thrown. + * To prevent an exception from being thrown, you should call the hasChapterAxis() method to determine if the axis exists. + * @method getChapterAxis + * @return {Xmla.Dataset.Axis} The chapter Xmla.Dataset.Axis object. + */ + getChapterAxis: function(){ + return this.getAxis(Xmla.Dataset.AXIS_CHAPTERS); + }, + /** + * Determine if the chapter axis exists. + * @method hasChapterAxis + * @return {boolean} true if the chapter axis exists, false if it doesn't exist. + */ + hasChapterAxis: function(){ + return this.hasAxis(Xmla.Dataset.AXIS_CHAPTERS); + }, + /** + * Get the Section axis. This is the fifth axis, and has ordinal 4. If the section axis doesn't exist, an INVALID_AXIS exception is thrown. + * To prevent an exception from being thrown, you should call the hasSectionAxis() method to determine if the axis exists. + * @method getSectionAxis + * @return {Xmla.Dataset.Axis} The section Xmla.Dataset.Axis object. + */ + getSectionAxis: function(){ + return this.getAxis(Xmla.Dataset.AXIS_SECTIONS); + }, + /** + * Determine if the section axis exists. + * @method hasSectionAxis + * @return {boolean} true if the section axis exists, false if it doesn't exist. + */ + hasSectionAxis: function(){ + return this.hasAxis(Xmla.Dataset.AXIS_SECTIONS); + }, + /** + * Get the Slicer axis. This is the axis that appears in the WHERE clause of the MDX statement. + * @method getSlicerAxis + * @return {Xmla.Dataset.Axis} The slicer Xmla.Dataset.Axis object. + */ + getSlicerAxis: function(){ + return this._slicer; + }, + /** + * Determine if the slicer axis exists. + * @method hasSlicerAxis + * @return {boolean} true if the slicer axis exists, false if it doesn't exist. + */ + hasSlicerAxis: function(){ + return this._slicer !== null; + }, + /** + * Get the Cellset object. + * @method getCellset + * @return {Xmla.Dataset.Cellset} The Xmla.Dataset.Cellset object. + */ + getCellset: function(){ + return this._cellset; + }, + /** + *

Calculate the cellset ordinal for the argument tuple indexes.

+ *

This method accepts a variable number of tuple indexes. One integer argument must be passed for each proper axis (excluding the slicer axis). + * Each integer arguments represent the index of a tuple on the respective axis.

+ *

The arguments must be specified by descending axis order. So if the data set has two axes (a row and a column axis), + * this method expects the tuple index of a tuple on the row axis first, and after that, the tuple index on the column axis.

+ *

The method returns an integer that represents the ordinal of the cell identified by the tuples specified by the tuple index arguments. + * One could use this ordinal as argument to the getByOrdinal() method of this Dataset's Cellset.

+ *

Instead of calling this method and passing the result into the Cellsets getByOrdinal() method, + * you can call the getByTupleIndexes() method of this Dataset's Cellset.

+ * @method cellOrdinalForTupleIndexes + * @param {int} A variable number of integer tuple indexes. Tuple indexes should be passed in descending order of axes. + * @return {int} The ordinal number that identifies the cell from this Dataset's Xmla.Dataset.Cellset that belongs to the tuples identified by the arguments. + */ + cellOrdinalForTupleIndexes: function() { + var numAxes = this._numAxes, axesOrder = this._axesOrder, i, ordinal = 0, a, arg, j, tupleCount; + //for each axis, in descending order + for (a = 0, i = numAxes - 1; i >= 0; i--, a++) { + arg = arguments[a]; + tupleCount = 1; + //for all preceding axes, in descending order + for (j = i-1; j >= 0; j--) { + tupleCount *= axesOrder[j].tupleCount(); } - else //property didnt exist for this key yet. - if (i === last) m[v] = row; //last keypart: store the row here - else m = m[v] = {}; //more keyparts to go: add a new map for this keypart - } - }, -/** -* Fetch all rows as an object, store them as proprties in an object (which acts as map). -* @method mapAllAsObject -* @param key {string|array} OPTIONAL. A column name or an array of column names that will be used to generate property names for the map. If not specified, the default key is used. If there is no default key, all column names will be used. -* @param map {object} OPTIONAL. The object that is used as map. Rows are added as properties to this map. If not specified, a new object is created -* @return {object} -*/ - mapAllAsObject: function(key, map){ - if (!map) map = {}; - if (!key) key = this.getKey(); - var row; - while (row = this.fetchAsObject()) this.mapAsObject(map, key, row); - return map; - }, - -/* -* Find a key for the resultset type. -*/ - getKey: function(){ - return (this._type) ? Xmla.Rowset.KEYS[this._type] : this.getFieldNames(); - } -}; - -/** -*

-* This class implements an XML/A multidimensional Dataset object. -*

-*

-* You do not need to instantiate objects of this class yourself. -* Rather, the Xmla class will instantiate this class -* to convey the result of the executeMultiDimensional method -* (see executeMultiDimensional()), -* and possibly the execute method. -* (Note that the execute() instantiates either the -* Xmla.Rowset or the Xmla.Dataset class -* depending on the value of the Format property in the options passed to the execute() method.) -*

-*

-* An instance of the Xmla.Dataset class may be returned immediately as return value from these methods when doing a synchronous request. -* In addition, the Xmla.Dataset object is available in the eventdata passed to any registered listeners -* (see addListener()). -*

-* -* @class Xmla.Dataset -* @constructor -* @param {DOMDocument} doc The responseXML result returned by server in response to a Execute request. -*/ -Xmla.Dataset = function(doc){ - if (typeof(doc) === "string") { - doc = _xjs(doc); - } - this._initDataset(doc); - return this; -} - -/** -* Can be used as argument for getAxis() to get the first axis (the column axis). -* Alternatively you can simply call getColumnAxis() -* @property AXIS_COLUMNS -* @static -* @final -* @type int -* @default 0 -*/ -Xmla.Dataset.AXIS_COLUMNS = 0; -/** -* Can be used as argument for getAxis() to get the second axis (the row axis). -* Alternatively you can simply call getRowAxis() -* @property AXIS_ROWS -* @static -* @final -* @type int -* @default 1 -*/ -Xmla.Dataset.AXIS_ROWS = 1; -/** -* Can be used as argument for getAxis() to get the third axis (the page axis). -* Alternatively you can simply call getPageAxis() -* @property AXIS_PAGES -* @static -* @final -* @type int -* @default 2 -*/ -Xmla.Dataset.AXIS_PAGES = 2; -/** -* Can be used as argument for getAxis() to get the fourth axis (the section axis). -* Alternatively you can simply call getSectionAxis() -* @property AXIS_SECTIONS -* @static -* @final -* @type int -* @default 3 -*/ -Xmla.Dataset.AXIS_SECTIONS = 3; -/** -* Can be used as argument for getAxis() to get the fifth axis (the chapters axis). -* Alternatively you can simply call getChapterAxis() -* @property AXIS_CHAPTERS -* @static -* @final -* @type int -* @default 4 -*/ -Xmla.Dataset.AXIS_CHAPTERS = 4; -/** -* Can be used as argument for getAxis() to get the slicer axis -* (the axis that appears in the WHERE clause of an MDX-SELECT statement). -* Alternatively you can simply call getSlicerAxis() -* @property AXIS_SLICER -* @static -* @final -* @type string -* @default SlicerAxis -*/ -Xmla.Dataset.AXIS_SLICER = "SlicerAxis"; - -Xmla.Dataset.prototype = { - _root: null, - _axes: null, - _axesOrder: null, - _numAxes: null, - _slicer: null, - _cellset:null, - _initDataset: function(doc){ - this._initRoot(doc); - this.cubeName = _getElementText( - _getElementsByTagNameNS( - this._root, _xmlnsDataset, "", "CubeName" - )[0] - ); - this._initAxes(); - this._initCells(); -/* - var a, i, j, func, funcBody = "", mul; - func = "var ordinal = 0, a;" + - "\nif (arguments.length !== " + this._numAxes + ") new Xmla.Exception._newError(\"ERROR_ILLEGAL_ARGUMENT\", \"cellOrdinalForTupleIndexes\", this)._throw();" - for (a = 0, i = this._numAxes-1; i >= 0; i--, a++) { - func += "\nif (typeof(a = arguments[" + a + "])!==\"number\") new Xmla.Exception._newError(\"ERROR_ILLEGAL_ARGUMENT\", \"cellOrdinalForTupleIndexes\", this)._throw();"; - mul = 1; - for (j = i-1; j >= 0; j--) mul *= this._axesOrder[j].tupleCount(); - func += "\nordinal += a "; - if (i) func += "* " + mul + ";"; - } - func += funcBody + "\nreturn ordinal;" - this._cellset.cellOrdinalForTupleIndexes = this.cellOrdinalForTupleIndexes = new Function(func); -*/ - }, - _initRoot: function(doc){ - var root = _getElementsByTagNameNS(doc, _xmlnsDataset, "", "root"); - if (root.length) this._root = root[0]; - else - Xmla.Exception._newError( - "ERROR_PARSING_RESPONSE", - "Xmla.Dataset._initData", - doc - )._throw(); - }, - _initAxes: function(){ - var i, axis, axisNode, axisName, axisNodes, numAxisNodes, tmpAxes = {}; - - this._axes = {}; - this._axesOrder = []; - - //collect the axisInfo nodes - axisNodes = _getElementsByTagNameNS(this._root, _xmlnsDataset, "", "AxisInfo"); - numAxisNodes = axisNodes.length; - for (i = 0; i < numAxisNodes; i++) { - axisNode = axisNodes[i]; - axisName = _getAttribute(axisNode, "name"); - tmpAxes[axisName] = axisNode; - } - //collect the axis nodes - axisNodes = _getElementsByTagNameNS(this._root, _xmlnsDataset, "", "Axis"); - numAxisNodes = axisNodes.length; - for (i = 0; i < numAxisNodes; i++){ - axisNode = axisNodes[i]; - axisName = _getAttribute(axisNode, "name"); - axis = new Xmla.Dataset.Axis(this, tmpAxes[axisName], axisNode, axisName, i); - if (axisName === Xmla.Dataset.AXIS_SLICER) this._slicer = axis; - else { - this._axes[axisName] = axis; - this._axesOrder.push(axis); + ordinal += arg * tupleCount; + } + return ordinal; + }, + /** + * Gets all of the XML data into one JS object. The object consists of the following members: + * + * @method fetchAsObject + * @param cellsetAsObject {boolean} By default, cells are returned in an array. When this flag is true, the cells are returned in an object, using the cell ordinal as key. + * @return {Object} + */ + fetchAsObject: function(cellsetAsObject) { + var getHierarchyArray = function(axis){ + var h = axis.getHierarchies(); + var hierarchies = []; + var i, n = axis.numHierarchies; + for (i = 0; i < n; i++) { + hierarchies.push(axis.hierarchy(i)); } - } - this._numAxes = this._axesOrder.length; - }, - _initCells: function(){ - this._cellset = new Xmla.Dataset.Cellset(this); - }, -/** -* Get the number of proper axes in this Dataset. This is the number of axes that appears in the SELECT list, and excludes the slicer axis. -* @method axisCount -* @return {int} -*/ - axisCount: function(){ - return this._numAxes; - }, - _getAxis: function(nameOrIndex) { - var name, axis; - switch (typeof(nameOrIndex)) { - case "number": - axis = this._axesOrder[nameOrIndex]; - break; - case "string": - axis = (name === Xmla.Dataset.AXIS_SLICER) ? this._slicer : this._axes[name]; - break; - } - return axis; - }, -/** -* Get the axis specified by the argument index or name. -* If the axis does not exist, an INVALID_AXIS exception is thrown. -* To prevent an exception from being thrown, you should call the hasAxis() method to determine if the axis exists. -* Alternatively, you can call axisCount(), and use an integer argument between zero (inclusive) and axis count (exclusive). -* @method getAxis -* @param nameOrIndex {string | int} For int arguments, a value of 0 up to the number of axes. You can also use one of the AXIS_xxx constants. For string arguments, this method will match the name of the axis as it is returned in the XML/A response. These names are of the form AxisN where N is an ordinal that identifies the axis. -* @return {Xmla.Dataset.Axis} The Xmla.Dataset.Axis object that corresponds to the argument. -*/ - getAxis: function(nameOrIndex){ - if (nameOrIndex === Xmla.Dataset.AXIS_SLICER) return this._slicer; - var axis = this._getAxis(nameOrIndex); - if (!axis) - Xmla.Exception._newError( - "INVALID_AXIS", - "Xmla.Dataset.getAxis", - nameOrIndex - )._throw(); - return axis; - }, -/** -* Determine if the axis specified by the argument exists. -* @method hasAxis -* @param nameOrIndex {string | int} For int arguments, a value of 0 up to the number of axes. You can also use one of the AXIS_xxx constants. For string arguments, this method will match the name of the axis as it is returned in the XML/A response. These names are of the form AxisN where N is an ordinal that identifies the axis. -* @return {boolean} true if the specified axis exists, false if it doesn't exist. -*/ - hasAxis: function(nameOrIndex) { - var axis = this._getAxis(nameOrIndex); - return !_isUnd(axis); - }, -/** -* Get the Column axis. This is the first axis, and has ordinal 0. If the column axis doesn't exist, an INVALID_AXIS exception is thrown. -* To prevent an exception from being thrown, you should call the hasColumnAxis() method to determine if the axis exists. -* @method getColumnAxis -* @return {Xmla.Dataset.Axis} The column Xmla.Dataset.Axis object. -*/ - getColumnAxis: function(){ - return this.getAxis(Xmla.Dataset.AXIS_COLUMNS); - }, -/** -* Determine if the column axis exists. -* @method hasColumnAxis -* @return {boolean} true if the column axis exists, false if it doesn't exist. -*/ - hasColumnAxis: function(){ - return this.hasAxis(Xmla.Dataset.AXIS_COLUMNS); - }, -/** -* Get the Row axis. This is the second axis, and has ordinal 1. If the row axis doesn't exist, an INVALID_AXIS exception is thrown. -* To prevent an exception from being thrown, you should call the hasRowAxis() method to determine if the axis exists. -* @method getRowAxis -* @return {Xmla.Dataset.Axis} The row Xmla.Dataset.Axis object. -*/ - getRowAxis: function(){ - return this.getAxis(Xmla.Dataset.AXIS_ROWS); - }, -/** -* Determine if the row axis exists. -* @method hasRowAxis -* @return {boolean} true if the row axis exists, false if it doesn't exist. -*/ - hasRowAxis: function(){ - return this.hasAxis(Xmla.Dataset.AXIS_ROWS); - }, -/** -* Get the Page axis. This is the third axis, and has ordinal 2. If the page axis doesn't exist, an INVALID_AXIS exception is thrown. -* To prevent an exception from being thrown, you should call the hasPageAxis() method to determine if the axis exists. -* @method getPageAxis -* @return {Xmla.Dataset.Axis} The page Xmla.Dataset.Axis object. -*/ - getPageAxis: function(){ - return this.getAxis(Xmla.Dataset.AXIS_PAGES); - }, -/** -* Determine if the page axis exists. -* @method hasPageAxis -* @return {boolean} true if the page axis exists, false if it doesn't exist. -*/ - hasPageAxis: function(){ - return this.hasAxis(Xmla.Dataset.AXIS_PAGES); - }, -/** -* Get the Chapter axis. This is the fourth axis, and has ordinal 3. If the chapter axis doesn't exist, an INVALID_AXIS exception is thrown. -* To prevent an exception from being thrown, you should call the hasChapterAxis() method to determine if the axis exists. -* @method getChapterAxis -* @return {Xmla.Dataset.Axis} The chapter Xmla.Dataset.Axis object. -*/ - getChapterAxis: function(){ - return this.getAxis(Xmla.Dataset.AXIS_CHAPTERS); - }, -/** -* Determine if the chapter axis exists. -* @method hasChapterAxis -* @return {boolean} true if the chapter axis exists, false if it doesn't exist. -*/ - hasChapterAxis: function(){ - return this.hasAxis(Xmla.Dataset.AXIS_CHAPTERS); - }, -/** -* Get the Section axis. This is the fifth axis, and has ordinal 4. If the section axis doesn't exist, an INVALID_AXIS exception is thrown. -* To prevent an exception from being thrown, you should call the hasSectionAxis() method to determine if the axis exists. -* @method getSectionAxis -* @return {Xmla.Dataset.Axis} The section Xmla.Dataset.Axis object. -*/ - getSectionAxis: function(){ - return this.getAxis(Xmla.Dataset.AXIS_SECTIONS); - }, -/** -* Determine if the section axis exists. -* @method hasSectionAxis -* @return {boolean} true if the section axis exists, false if it doesn't exist. -*/ - hasSectionAxis: function(){ - return this.hasAxis(Xmla.Dataset.AXIS_SECTIONS); - }, -/** -* Get the Slicer axis. This is the axis that appears in the WHERE clause of the MDX statement. -* @method getSlicerAxis -* @return {Xmla.Dataset.Axis} The slicer Xmla.Dataset.Axis object. -*/ - getSlicerAxis: function(){ - return this._slicer; - }, -/** -* Determine if the slicer axis exists. -* @method hasSlicerAxis -* @return {boolean} true if the slicer axis exists, false if it doesn't exist. -*/ - hasSlicerAxis: function(){ - return this._slicer !== null; - }, -/** -* Get the Cellset object. -* @method getCellset -* @return {Xmla.Dataset.Cellset} The Xmla.Dataset.Cellset object. -*/ - getCellset: function(){ - return this._cellset; - }, -/** -*

Calculate the cellset ordinal for the argument tuple indexes.

-*

This method accepts a variable number of tuple indexes. One integer argument must be passed for each proper axis (excluding the slicer axis). -* Each integer arguments represent the index of a tuple on the respective axis.

-*

The arguments must be specified by descending axis order. So if the data set has two axes (a row and a column axis), -* this method expects the tuple index of a tuple on the row axis first, and after that, the tuple index on the column axis.

-*

The method returns an integer that represents the ordinal of the cell identified by the tuples specified by the tuple index arguments. -* One could use this ordinal as argument to the getByOrdinal() method of this Dataset's Cellset.

-*

Instead of calling this method and passing the result into the Cellsets getByOrdinal() method, -* you can call the getByTupleIndexes() method of this Dataset's Cellset.

-* @method cellOrdinalForTupleIndexes -* @param {int} A variable number of integer tuple indexes. Tuple indexes should be passed in descending order of axes. -* @return {int} The ordinal number that identifies the cell from this Dataset's Xmla.Dataset.Cellset that belongs to the tuples identified by the arguments. -*/ - cellOrdinalForTupleIndexes: function() { - var numAxes = this._numAxes, axesOrder = this._axesOrder, i, ordinal = 0, a, arg, j, tupleCount; - //for each axis, in descending order - for (a = 0, i = numAxes - 1; i >= 0; i--, a++) { - arg = arguments[a]; - tupleCount = 1; - //for all preceding axes, in descending order - for (j = i-1; j >= 0; j--) { - tupleCount *= axesOrder[j].tupleCount(); - } - ordinal += arg * tupleCount; - } - return ordinal; - }, -/** - * Gets all of the XML data into one JS object. The object consists of the following members: - * - * @method fetchAsObject - * @param cellsetAsObject {boolean} By default, cells are returned in an array. When this flag is true, the cells are returned in an object, using the cell ordinal as key. - * @return {Object} - */ - fetchAsObject: function(cellsetAsObject) { - var getHierarchyArray = function(axis){ - var h = axis.getHierarchies(); - var hierarchies = []; - var i, n = axis.numHierarchies; - for (i = 0; i < n; i++) { - hierarchies.push(axis.hierarchy(i)); - } - return hierarchies; - } - var axes = [], axis, filterAxis, - cellset = [], cells = [], cell, - i, n, tuples=1, idx=0; - - //loop through all non slicer axes - for (i = 0, n = this.axisCount(); i < n; i++){ - axis = this.getAxis(i); - tuples = tuples * axis.tupleCount(); - axes.push({ + return hierarchies; + } + var axes = [], axis, filterAxis, + cellset = [], cells = [], cell, + i, n, tuples=1, idx=0; + + //loop through all non slicer axes + for (i = 0, n = this.axisCount(); i < n; i++){ + axis = this.getAxis(i); + tuples = tuples * axis.tupleCount(); + axes.push({ + positions: axis.fetchAllAsObject(), + hierarchies: getHierarchyArray(axis) + }); + } + + //get Slicer information + if (this.hasSlicerAxis()) { + axis = this.getSlicerAxis(); + filterAxis = { positions: axis.fetchAllAsObject(), - hierarchies: getHierarchyArray(axis) - }); - } - - //get Slicer information - if (this.hasSlicerAxis()) { - axis = this.getSlicerAxis(); - filterAxis = { - positions: axis.fetchAllAsObject(), - hierarchies: getHierarchyArray(axis) - } - } else { - filterAxis = { - positions: {}, - hierarchies: [] - } - } - - //get Cellset data - cellset = this.getCellset(); - if (cellsetAsObject === true) { - cells = cellset.fetchAllAsObject(); - } - else { - for (i = 0, n = tuples; i < n; i++){ - cell = cellset.readCell(); - if (idx === cell.ordinal) { - cells.push(cell); - if (cellset.nextCell() === -1) { - break; - } - } else { - //console.debug('skipping: '+idx+':'+cell.ordinal); - cells.push({Value:null, FmtValue:null, FormatString: null, ordinal:idx }); + hierarchies: getHierarchyArray(axis) + } + } else { + filterAxis = { + positions: {}, + hierarchies: [] + } + } + + //get Cellset data + cellset = this.getCellset(); + if (cellsetAsObject === true) { + cells = cellset.fetchAllAsObject(); + } + else { + for (i = 0, n = tuples; i < n; i++){ + cell = cellset.readCell(); + if (idx === cell.ordinal) { + cells.push(cell); + if (cellset.nextCell() === -1) { + break; + } + } else { + //console.debug('skipping: '+idx+':'+cell.ordinal); + cells.push({Value:null, FmtValue:null, FormatString: null, ordinal:idx }); + } + idx++; } - idx++; - } - } - //do not close, it might be used later..... - cellset.reset(); - - return { - cubeName: this.cubeName, - axes: axes, - filterAxis: filterAxis, - cells: cells - }; - }, -/** -* Reset this object so it can be used again. -* @method reset -* @return void -*/ - reset: function(){ - if (this._cellset) this._cellset.reset(); - if (this._axes) { - var i, n, axis; - for (i = 0, n = this.axisCount(); i < n; i++){ - this.getAxis(i).reset(); - } - } - }, -/** -* Cleanup this Dataset object. -* @method close -* @return void -*/ - close: function(){ - if (this._slicer) { - this._slicer.close(); - } - var i, n = this._numAxes; - for (i = 0; i < n; i++) { - this.getAxis(i).close(); + } + //do not close, it might be used later..... + cellset.reset(); + + return { + cubeName: this.cubeName, + axes: axes, + filterAxis: filterAxis, + cells: cells + }; + }, + /** + * Reset this object so it can be used again. + * @method reset + * @return void + */ + reset: function(){ + if (this._cellset) this._cellset.reset(); + if (this._axes) { + var i, n, axis; + for (i = 0, n = this.axisCount(); i < n; i++){ + this.getAxis(i).reset(); + } + } + }, + /** + * Cleanup this Dataset object. + * @method close + * @return void + */ + close: function(){ + if (this._slicer) { + this._slicer.close(); + } + var i, n = this._numAxes; + for (i = 0; i < n; i++) { + this.getAxis(i).close(); + } + this._cellset.close(); + this._cellset = null; + this._root = null; + this._axes = null; + this._axesOrder = null; + this._numAxes = null; + this._slicer = null; } - this._cellset.close(); - this._cellset = null; - this._root = null; - this._axes = null; - this._axesOrder = null; - this._numAxes = null; - this._slicer = null; + }; + + /** + *

+ * This class implements an Axis object. + *

+ *

+ * You do not need to instantiate objects of this class yourself. + * Rather, the Xmla.Dataset class creates instances of this class to represent the axes of an MDX query. + * (see getAxis().) + * + * @class Xmla.Dataset.Axis + * @constructor + */ + Xmla.Dataset.Axis = function(_dataset, _axisInfoNode, _axisNode, name, id){ + this._dataset = _dataset; + this._initAxis(_axisInfoNode, _axisNode); + this.name = name; + this.id = id; + return this; } -}; - -/** -*

-* This class implements an Axis object. -*

-*

-* You do not need to instantiate objects of this class yourself. -* Rather, the Xmla.Dataset class creates instances of this class to represent the axes of an MDX query. -* (see getAxis().) -* -* @class Xmla.Dataset.Axis -* @constructor -*/ -Xmla.Dataset.Axis = function(_dataset, _axisInfoNode, _axisNode, name, id){ - this._dataset = _dataset; - this._initAxis(_axisInfoNode, _axisNode); - this.name = name; - this.id = id; - return this; -} - -/** -* The name of the standard member property that contains the unique name for this member. -* See Ole DB standard for more information. -* @property MEMBER_UNIQUE_NAME -* @static -* @final -* @type string -* @default Uname -*/ -Xmla.Dataset.Axis.MEMBER_UNIQUE_NAME = "UName"; -/** -* The name of the standard member property that contains the caption for this member. -* See Ole DB standard for more information. -* @property MEMBER_CAPTION -* @static -* @final -* @type string -* @default Caption -*/ -Xmla.Dataset.Axis.MEMBER_CAPTION = "Caption"; -/** -* The name of the standard member property that contains the name of the level for this member. -* See Ole DB standard for more information. -* @property MEMBER_LEVEL_NAME -* @static -* @final -* @type string -* @default LName -*/ -Xmla.Dataset.Axis.MEMBER_LEVEL_NAME = "LName"; -/** -* The name of the standard member property that contains the number of the level for this member. -* See Ole DB standard for more information. -* @property MEMBER_LEVEL_NUMBER -* @static -* @final -* @type string -* @default LNum -*/ -Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER = "LNum"; -/** -* The name of the member property that contains displayinfo for this member. -* See Ole DB standard for more information. -* @property MEMBER_DISPLAY_INFO -* @static -* @final -* @type string -* @default LNum -*/ -Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO = "DisplayInfo"; -/** -* The default mem ber properties for members -* See Ole DB standard for more information. -* @property DefaultMemberProperties -* @static -* @final -* @type array -*/ -Xmla.Dataset.Axis.DefaultMemberProperties = [ - Xmla.Dataset.Axis.MEMBER_UNIQUE_NAME, - Xmla.Dataset.Axis.MEMBER_CAPTION, - Xmla.Dataset.Axis.MEMBER_LEVEL_NAME, - Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER, - Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO -]; - -/** -* A constant that can be used as a bitmask for a member's DisplayInfo property. -* Bitwise AND-ing this mask to the member's DisplayInfo property returns an estimate of the number of children of this member. -* @property MDDISPINFO_CHILDREN_CARDINALITY -* @static -* @final -* @type int -* @default 65535 -*/ -Xmla.Dataset.Axis.MDDISPINFO_CHILDREN_CARDINALITY = 65535; -/** -* A constant that can be used as a bitmask for a member's DisplayInfo property. -* If this bit is set, it means the member is drilled down. -* This is the case whenever at least one child of this member appears on the axis immediately following this member. -* @property MDDISPINFO_DRILLED_DOWN -* @static -* @final -* @type int -* @default 65536 -*/ -Xmla.Dataset.Axis.MDDISPINFO_DRILLED_DOWN = 65536; -/** -* A constant that can be used as a bitmask for a member's DisplayInfo property. -* If this bit is set, it means this member has the same parent as the member immediately preceding this member. -* @property MDDISPINFO_SAME_PARENT_AS_PREV -* @static -* @final -* @type int -* @default 131072 -*/ -Xmla.Dataset.Axis.MDDISPINFO_SAME_PARENT_AS_PREV = 131072; - -Xmla.Dataset.Axis.prototype = { -/** -* The 0-based id of the axis. -* @property id -* @type int -*/ - id: -1, -/** -* The name of the axis. -* @property name -* @type string -*/ - name: null, - _dataset: null, - _tuples: null, - _members: null, - _memberProperties: null, - numTuples: null, - numHierarchies: null, - _tupleIndex: null, - _hierarchyIndex: null, - _hierarchyOrder: null, - _hierarchyDefs: null, - _hierarchyIndexes: null, - _initHierarchies: function(_axisInfoNode){ - var hierarchyInfoNodes = _getElementsByTagNameNS( - _axisInfoNode, - _xmlnsDataset, - "", - "HierarchyInfo" - ), - numHierarchies = hierarchyInfoNodes.length, - i, j, hierarchyInfoNode, hierarchyName, - hierarchyDef, properties, numPropertyNodes, propertyNodes, propertyNode, - nodeName, type, memberProperty, memberProperties = this._memberProperties, - converter - ; - this._hierarchyDefs = {}; - this._hierarchyOrder = []; - this._hierarchyIndexes = {}; - this.numHierarchies = numHierarchies; - var propertyTagName, propertyName; - for (i = 0; i < numHierarchies; i++){ - hierarchyInfoNode = hierarchyInfoNodes[i]; - hierarchyName = _getAttribute(hierarchyInfoNode, "name"); - this._hierarchyOrder[i] = hierarchyName; - this._hierarchyIndexes[hierarchyName] = i; - hierarchyDef = { - index: i, - name: hierarchyName, - properties: properties = {} - }; - propertyNodes = _getElementsByTagNameNS(hierarchyInfoNode, _xmlnsDataset, "", "*"); - numPropertyNodes = propertyNodes.length; - for (j = 0; j < numPropertyNodes; j++) { - propertyNode = propertyNodes[j]; - nodeName = propertyNode.nodeName; - //note: MSAS doesn't seem to include a type for custom properties - type = _getAttribute(propertyNode, "type"); - if (!type) { - memberProperty = memberProperties[nodeName]; - if (memberProperty) { - type = memberProperty.type; - } - else { - switch (nodeName) { + + /** + * The name of the standard member property that contains the unique name for this member. + * See Ole DB standard for more information. + * @property MEMBER_UNIQUE_NAME + * @static + * @final + * @type string + * @default Uname + */ + Xmla.Dataset.Axis.MEMBER_UNIQUE_NAME = "UName"; + /** + * The name of the standard member property that contains the caption for this member. + * See Ole DB standard for more information. + * @property MEMBER_CAPTION + * @static + * @final + * @type string + * @default Caption + */ + Xmla.Dataset.Axis.MEMBER_CAPTION = "Caption"; + /** + * The name of the standard member property that contains the name of the level for this member. + * See Ole DB standard for more information. + * @property MEMBER_LEVEL_NAME + * @static + * @final + * @type string + * @default LName + */ + Xmla.Dataset.Axis.MEMBER_LEVEL_NAME = "LName"; + /** + * The name of the standard member property that contains the number of the level for this member. + * See Ole DB standard for more information. + * @property MEMBER_LEVEL_NUMBER + * @static + * @final + * @type string + * @default LNum + */ + Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER = "LNum"; + /** + * The name of the member property that contains displayinfo for this member. + * See Ole DB standard for more information. + * @property MEMBER_DISPLAY_INFO + * @static + * @final + * @type string + * @default LNum + */ + Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO = "DisplayInfo"; + /** + * The default mem ber properties for members + * See Ole DB standard for more information. + * @property DefaultMemberProperties + * @static + * @final + * @type array + */ + Xmla.Dataset.Axis.DefaultMemberProperties = [ + Xmla.Dataset.Axis.MEMBER_UNIQUE_NAME, + Xmla.Dataset.Axis.MEMBER_CAPTION, + Xmla.Dataset.Axis.MEMBER_LEVEL_NAME, + Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER, + Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO + ]; + + /** + * A constant that can be used as a bitmask for a member's DisplayInfo property. + * Bitwise AND-ing this mask to the member's DisplayInfo property returns an estimate of the number of children of this member. + * @property MDDISPINFO_CHILDREN_CARDINALITY + * @static + * @final + * @type int + * @default 65535 + */ + Xmla.Dataset.Axis.MDDISPINFO_CHILDREN_CARDINALITY = 65535; + /** + * A constant that can be used as a bitmask for a member's DisplayInfo property. + * If this bit is set, it means the member is drilled down. + * This is the case whenever at least one child of this member appears on the axis immediately following this member. + * @property MDDISPINFO_DRILLED_DOWN + * @static + * @final + * @type int + * @default 65536 + */ + Xmla.Dataset.Axis.MDDISPINFO_DRILLED_DOWN = 65536; + /** + * A constant that can be used as a bitmask for a member's DisplayInfo property. + * If this bit is set, it means this member has the same parent as the member immediately preceding this member. + * @property MDDISPINFO_SAME_PARENT_AS_PREV + * @static + * @final + * @type int + * @default 131072 + */ + Xmla.Dataset.Axis.MDDISPINFO_SAME_PARENT_AS_PREV = 131072; + + Xmla.Dataset.Axis.prototype = { + /** + * The 0-based id of the axis. + * @property id + * @type int + */ + id: -1, + /** + * The name of the axis. + * @property name + * @type string + */ + name: null, + _dataset: null, + _tuples: null, + _members: null, + _memberProperties: null, + numTuples: null, + numHierarchies: null, + _tupleIndex: null, + _hierarchyIndex: null, + _hierarchyOrder: null, + _hierarchyDefs: null, + _hierarchyIndexes: null, + _initHierarchies: function(_axisInfoNode){ + var hierarchyInfoNodes = _getElementsByTagNameNS( + _axisInfoNode, + _xmlnsDataset, + "", + "HierarchyInfo" + ), + numHierarchies = hierarchyInfoNodes.length, + i, j, hierarchyInfoNode, hierarchyName, + hierarchyDef, properties, numPropertyNodes, propertyNodes, propertyNode, + nodeName, type, memberProperty, memberProperties = this._memberProperties, + converter + ; + this._hierarchyDefs = {}; + this._hierarchyOrder = []; + this._hierarchyIndexes = {}; + this.numHierarchies = numHierarchies; + var propertyTagName, propertyName; + for (i = 0; i < numHierarchies; i++){ + hierarchyInfoNode = hierarchyInfoNodes[i]; + hierarchyName = _getAttribute(hierarchyInfoNode, "name"); + this._hierarchyOrder[i] = hierarchyName; + this._hierarchyIndexes[hierarchyName] = i; + hierarchyDef = { + index: i, + name: hierarchyName, + properties: properties = {} + }; + propertyNodes = _getElementsByTagNameNS(hierarchyInfoNode, _xmlnsDataset, "", "*"); + numPropertyNodes = propertyNodes.length; + for (j = 0; j < numPropertyNodes; j++) { + propertyNode = propertyNodes[j]; + nodeName = propertyNode.nodeName; + //note: MSAS doesn't seem to include a type for custom properties + type = _getAttribute(propertyNode, "type"); + if (!type) { + memberProperty = memberProperties[nodeName]; + if (memberProperty) { + type = memberProperty.type; + } + else { + switch (nodeName) { + case Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER: + case Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO: + type = "xsd:int"; + } + } + } + converter = _typeConverterMap[type]; + if (!converter){ + converter = _textConverter; + } + propertyTagName = _decodeXmlaTagName(nodeName); + switch (propertyTagName) { + case Xmla.Dataset.Axis.MEMBER_UNIQUE_NAME: + case Xmla.Dataset.Axis.MEMBER_CAPTION: + case Xmla.Dataset.Axis.MEMBER_LEVEL_NAME: case Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER: case Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO: - type = "xsd:int"; - } - } - } - converter = _typeConverterMap[type]; - if (!converter){ - converter = _textConverter; - } - propertyTagName = _decodeXmlaTagName(nodeName); - switch (propertyTagName) { - case Xmla.Dataset.Axis.MEMBER_UNIQUE_NAME: - case Xmla.Dataset.Axis.MEMBER_CAPTION: - case Xmla.Dataset.Axis.MEMBER_LEVEL_NAME: - case Xmla.Dataset.Axis.MEMBER_LEVEL_NUMBER: - case Xmla.Dataset.Axis.MEMBER_DISPLAY_INFO: - //map default properties with their tagName (Standard) - propertyName = propertyTagName; - break; - default: - //map non-default properties by unqualified property name. - propertyName = _getAttribute(propertyNode, "name"); - if (propertyName) { - propertyName = propertyName.split("."); - propertyName = propertyName[propertyName.length - 1]; - if (propertyName.charAt(0) === "[" && propertyName.charAt(propertyName.length -1) === "]") { - propertyName = propertyName.substr(1, propertyName.length - 2); - } + //map default properties with their tagName (Standard) + propertyName = propertyTagName; + break; + default: + //map non-default properties by unqualified property name. + propertyName = _getAttribute(propertyNode, "name"); + if (propertyName) { + propertyName = propertyName.split("."); + propertyName = propertyName[propertyName.length - 1]; + if (propertyName.charAt(0) === "[" && propertyName.charAt(propertyName.length -1) === "]") { + propertyName = propertyName.substr(1, propertyName.length - 2); + } + } } + properties[nodeName] = { + converter: converter, + name: propertyTagName, + propertyName: propertyName + }; } - properties[nodeName] = { - converter: converter, - name: propertyTagName, - propertyName: propertyName + this._hierarchyDefs[hierarchyName] = hierarchyDef; + } + }, + _initMembers: function(){ + var root = this._dataset._root, + memberSchema, memberSchemaElements, numMemberSchemaElements, memberSchemaElement, + type, name, i, memberProperties = this._memberProperties = {} + ; + memberSchema = _getComplexType(root, "MemberType"); + if (!memberSchema) + Xmla.Exception._newError( + "ERROR_PARSING_RESPONSE", + "Xmla.DataSet.Axis", + root + )._throw(); + memberSchema = _getElementsByTagNameNS(memberSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "sequence"); + if (!memberSchema.length) { + //Jedox does not specify content of members. + if (!_isUnd(console.error)) { + console.error("MemberType in schema does not define any child elements. Are you running on Jedox/Palo?"); + } + return; + } + memberSchema = memberSchema[0]; + memberSchemaElements = _getElementsByTagNameNS(memberSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "element"); + numMemberSchemaElements = memberSchemaElements.length; + for (i = 0; i < numMemberSchemaElements; i++) { + memberSchemaElement = memberSchemaElements[i]; + type = _getAttribute(memberSchemaElement, "type"); + name = _getAttribute(memberSchemaElement, "name"); + memberProperties[name] = { + type: type, + converter: _typeConverterMap[type], + name: _decodeXmlaTagName(name) }; } - this._hierarchyDefs[hierarchyName] = hierarchyDef; - } - }, - _initMembers: function(){ - var root = this._dataset._root, - memberSchema, memberSchemaElements, numMemberSchemaElements, memberSchemaElement, - type, name, i, memberProperties = this._memberProperties = {} - ; - memberSchema = _getComplexType(root, "MemberType"); - if (!memberSchema) - Xmla.Exception._newError( - "ERROR_PARSING_RESPONSE", - "Xmla.DataSet.Axis", - root - )._throw(); - memberSchema = _getElementsByTagNameNS(memberSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "sequence"); - if (!memberSchema.length) { - //Jedox does not specify content of members. - if (!_isUnd(console.error)) { - console.error("MemberType in schema does not define any child elements. Are you running on Jedox/Palo?"); - } - return; - } - memberSchema = memberSchema[0]; - memberSchemaElements = _getElementsByTagNameNS(memberSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "element"); - numMemberSchemaElements = memberSchemaElements.length; - for (i = 0; i < numMemberSchemaElements; i++) { - memberSchemaElement = memberSchemaElements[i]; - type = _getAttribute(memberSchemaElement, "type"); - name = _getAttribute(memberSchemaElement, "name"); - memberProperties[name] = { - type: type, - converter: _typeConverterMap[type], - name: _decodeXmlaTagName(name) - }; - } - }, - _initAxis: function(_axisInfoNode, _axisNode){ - this.name = _getAttribute(_axisNode, "name"); - this._initMembers(); - this._initHierarchies(_axisInfoNode); - this._tuples = _getElementsByTagNameNS(_axisNode, _xmlnsDataset, "", "Tuple"); - this.numTuples = this._tuples.length; - this.reset(); - }, - close: function(){ - this.numTuples = -1; - this._tuples = null; - this._hierarchyDefs = null; - this._hierarchyOrder = null; - this._hierarchyIndexes = null; - this._members = null; - }, - _getMembers: function(){ - if (!this.hasMoreTuples()) { - return null; - } - return _getElementsByTagNameNS( - this._tuples[this._tupleIndex], - _xmlnsDataset, "", "Member" - ); - }, -/** -* Resets this axis object. -* This resets internal counters for iterating through the hierarchies and tuples of this Axis object. -* When using hierarchy and tuple iterators to traverse the entire axis, you typically won't need to call this method yourself. -* @method reset -*/ - reset: function(){ - this._hierarchyIndex = 0; - this._tupleIndex = 0; - this._members = this._getMembers(); - }, -/** -* Checks if there are more hierarchies to iterate through. -* You can use this method along with the nextHierarchy() method to drive a loop -* to iterate through the hierarchies contained in this axis object. -* @method hasMoreHierarchies -* @return {boolean} Returns true if there are more hierarchies to vist, false if all hierarchies are traversed. -*/ - hasMoreHierarchies: function(){ - return this.numHierarchies > this._hierarchyIndex; - }, -/** -* Moves the internal hierarchy pointer forward. -* You can use this method along with the hasMoreHierarchies() method to drive a loop -* to iterate through the hierarchies contained in this axis object. -* @method nextHierarchy -* @return {int} Returns the index of current hierarchy. -*/ - nextHierarchy: function(){ - return this._hierarchyIndex++; - }, -/** -*

Calls a callback function for each hierarchy in this Axis object.

-*

The callback function is passed an object that represents the current hierarchy. This object has the following structure:

-*

The callback may return false to abort iteration. If the callback does not return false, iteration will resume until all hierarchies are traversed.

-* @param {function()} callback A function that will be called for each hierarchy. The hierarchy is passed as an object as the first argument to the callback. For the structure of the hierarchy object, see hierarchy(). -* @param {object} scope The object that will be used as scope when executing the callback function. If this is undefined or null, the Axis' this pointer will be used. -* @param {object} args Additional data to be passed to the callback function.. -* @method eachHierarchy -* @return {boolean} Returns true if all hierarchies were visited and the callback did not return false. Returns false if the callback returned false and further iteration was aborted. -*/ - eachHierarchy: function(callback, scope, args){ - var mArgs = [null]; - if (!scope) scope = this; - if (args) { - if (!_isArr(args)) args = [args]; - mArgs = mArgs.concat(args); - } - while (this.hasMoreHierarchies()){ - mArgs[0] = this._hierarchyDefs[this._hierarchyOrder[this._hierarchyIndex]]; - if (callback.apply(scope, mArgs)===false) return false; - this.nextHierarchy(); - } - this._hierarchyIndex = 0; - return true; - }, -/** -* Checks if there are more tuples to iterate through. -* You can use this method along with the nextTuple() method to drive a loop -* to iterate through the tuples contained in this axis object. -* @method hasMoreTuples -* @return {boolean} Returns true if there are more tuples to vist, false if all tuples are traversed. -*/ - hasMoreTuples: function(){ - return this.numTuples > this._tupleIndex; - }, -/** -* Moves the internal tuple pointer forward. -* You can use this method along with the nextTuple() method to drive a loop -* to iterate through the tuples contained in this axis object. -* @method nextTuple -* @return {int} Returns the index of current tuple. -*/ - nextTuple: function(){ - this._tupleIndex++; - this._members = this._getMembers(); - return this._tupleIndex; - }, -/** -* Gets the number of tuples in this axis object. -* @method tupleCount -* @return {int} Returns the number of tuples in this Axis object. -*/ - tupleCount: function(){ - return this.numTuples; - }, -/** -* Returns the current value of the tuple pointer. -* @method tupleIndex -* @return {int} Returns the current value of the tuple pointer. -*/ - tupleIndex: function() { - return this._tupleIndex; - }, -/** -* Get the current tuple as an object. The tuple object has the following structure: -* @method getTuple -* @return {object} An object representing the current tuple.. -*/ - getTuple: function() { - var i, n = this.numHierarchies, - hierarchies = {}, member, members = [], - tuple = { - index: this._tupleIndex, - hierarchies: hierarchies, - members: members + }, + _initAxis: function(_axisInfoNode, _axisNode){ + this.name = _getAttribute(_axisNode, "name"); + this._initMembers(); + this._initHierarchies(_axisInfoNode); + this._tuples = _getElementsByTagNameNS(_axisNode, _xmlnsDataset, "", "Tuple"); + this.numTuples = this._tuples.length; + this.reset(); + }, + close: function(){ + this.numTuples = -1; + this._tuples = null; + this._hierarchyDefs = null; + this._hierarchyOrder = null; + this._hierarchyIndexes = null; + this._members = null; + }, + _getMembers: function(){ + if (!this.hasMoreTuples()) { + return null; } - ; - for (i=0; i < n; i++) { - member = this._member(i); - hierarchies[this._hierarchyOrder[i]] = member; - members.push(member); - } - return tuple; - }, -/** -*

Calls a callback function for each tuple in this Axis object.

-*

The callback function is passed an object that represents the current tuple. (see getTuple() for a description of the tuple format.)

-*

The callback may return false to abort iteration. If the callback does not return false, iteration will resume until all tuples are traversed.

-* @param {function()} callback A function that will be called for each tuple. The tuple is passed as an object as the first argument to the callback. -* @param {object} scope The object that will be used as scope when executing the callback function. If this is undefined or null, the Axis' this pointer will be used. -* @param {object} args Additional data to be passed as the second argument to the callback function. -* @method eachTuple -* @return {boolean} Returns true if all tuples were visited and the callback did not return false. Returns false if the callback returned false and further iteration was aborted. -*/ - eachTuple: function(callback, scope, args){ - var mArgs = [null]; - if (!scope) { - scope = this; - } - if (args) { - if (_isArr(args)) { - mArgs.concat(args) + return _getElementsByTagNameNS( + this._tuples[this._tupleIndex], + _xmlnsDataset, "", "Member" + ); + }, + /** + * Resets this axis object. + * This resets internal counters for iterating through the hierarchies and tuples of this Axis object. + * When using hierarchy and tuple iterators to traverse the entire axis, you typically won't need to call this method yourself. + * @method reset + */ + reset: function(){ + this._hierarchyIndex = 0; + this._tupleIndex = 0; + this._members = this._getMembers(); + }, + /** + * Checks if there are more hierarchies to iterate through. + * You can use this method along with the nextHierarchy() method to drive a loop + * to iterate through the hierarchies contained in this axis object. + * @method hasMoreHierarchies + * @return {boolean} Returns true if there are more hierarchies to vist, false if all hierarchies are traversed. + */ + hasMoreHierarchies: function(){ + return this.numHierarchies > this._hierarchyIndex; + }, + /** + * Moves the internal hierarchy pointer forward. + * You can use this method along with the hasMoreHierarchies() method to drive a loop + * to iterate through the hierarchies contained in this axis object. + * @method nextHierarchy + * @return {int} Returns the index of current hierarchy. + */ + nextHierarchy: function(){ + return this._hierarchyIndex++; + }, + /** + *

Calls a callback function for each hierarchy in this Axis object.

+ *

The callback function is passed an object that represents the current hierarchy. This object has the following structure:

+ *

The callback may return false to abort iteration. If the callback does not return false, iteration will resume until all hierarchies are traversed.

+ * @param {function()} callback A function that will be called for each hierarchy. The hierarchy is passed as an object as the first argument to the callback. For the structure of the hierarchy object, see hierarchy(). + * @param {object} scope The object that will be used as scope when executing the callback function. If this is undefined or null, the Axis' this pointer will be used. + * @param {object} args Additional data to be passed to the callback function.. + * @method eachHierarchy + * @return {boolean} Returns true if all hierarchies were visited and the callback did not return false. Returns false if the callback returned false and further iteration was aborted. + */ + eachHierarchy: function(callback, scope, args){ + var mArgs = [null]; + if (!scope) scope = this; + if (args) { + if (!_isArr(args)) args = [args]; + mArgs = mArgs.concat(args); } - else { - mArgs.push(args); + while (this.hasMoreHierarchies()){ + mArgs[0] = this._hierarchyDefs[this._hierarchyOrder[this._hierarchyIndex]]; + if (callback.apply(scope, mArgs)===false) return false; + this.nextHierarchy(); } - } - while (this.hasMoreTuples()){ - mArgs[0] = this.getTuple(); - if (callback.apply(scope, mArgs) === false) { - return false; + this._hierarchyIndex = 0; + return true; + }, + /** + * Checks if there are more tuples to iterate through. + * You can use this method along with the nextTuple() method to drive a loop + * to iterate through the tuples contained in this axis object. + * @method hasMoreTuples + * @return {boolean} Returns true if there are more tuples to vist, false if all tuples are traversed. + */ + hasMoreTuples: function(){ + return this.numTuples > this._tupleIndex; + }, + /** + * Moves the internal tuple pointer forward. + * You can use this method along with the nextTuple() method to drive a loop + * to iterate through the tuples contained in this axis object. + * @method nextTuple + * @return {int} Returns the index of current tuple. + */ + nextTuple: function(){ + this._tupleIndex++; + this._members = this._getMembers(); + return this._tupleIndex; + }, + /** + * Gets the number of tuples in this axis object. + * @method tupleCount + * @return {int} Returns the number of tuples in this Axis object. + */ + tupleCount: function(){ + return this.numTuples; + }, + /** + * Returns the current value of the tuple pointer. + * @method tupleIndex + * @return {int} Returns the current value of the tuple pointer. + */ + tupleIndex: function() { + return this._tupleIndex; + }, + /** + * Get the current tuple as an object. The tuple object has the following structure: + * @method getTuple + * @return {object} An object representing the current tuple.. + */ + getTuple: function() { + var i, n = this.numHierarchies, + hierarchies = {}, member, members = [], + tuple = { + index: this._tupleIndex, + hierarchies: hierarchies, + members: members + } + ; + for (i=0; i < n; i++) { + member = this._member(i); + hierarchies[this._hierarchyOrder[i]] = member; + members.push(member); } - this.nextTuple(); - } - this._tupleIndex = 0; - this._members = this._getMembers(); - return true; - }, -/** - * Returns the hierarchies of this Axis object. - * The hierarchies are returned as an object. The keys are the hierarchy names; the values are objects representing the hierarchies. - * The hierarchy object has the following properties: - * The properties always contain the intrinsic properties Caption, DisplayInfo, LName, LNum and UName. - * If any additional properties were included (for example, by having a MDX DIMENSION PROPERTIES clause then these will be included as well. -* @method getHierarchies -* @return {array} An object representing the hierarchies contained in this Axis. - **/ - getHierarchies: function(){ - return this._hierarchyDefs; - }, -/** - * Returns the names of the hierarchies of this Axis object. -* @method getHierarchyNames -* @return {array} An array of names of the hierarchies contained in this Axis. - **/ - getHierarchyNames: function(){ - var hierarchyNames = [], i, n = this.numHierarchies; - for (i = 0; i < n; i++) hierarchyNames[i] = this._hierarchyOrder[i]; - return hierarchyNames; - }, -/** -* Gets the number of hierarchies in this axis object. -* @method hierarchyCount -* @return {int} Returns the number of hierarchies in this Axis object. -*/ - hierarchyCount: function(){ - return this.numHierarchies; - }, -/** -* Gets the index of the hierarchy identified by the specified name, or the index of the current hierarchy (in case the name argument is omitted). -* @method hierarchyIndex -* @param hierarchyName {string} The name of the hierarchy for which the index is to be retrieved. When omitted, the index of the current hierarchy is returned. -* @return {int} The index of the hierarchy specified by the name passed as argument, or the index of the current hierarchy if the name argument is omitted. -*/ - hierarchyIndex: function(hierarchyName){ - if (_isUnd(hierarchyName)) return this._hierarchyIndex; - var index = this._hierarchyIndexes[hierarchyName]; - if (_isUnd(index)) - Xmla.Exception._newError( - "INVALID_HIERARCHY", - "Xmla.Dataset.Axis.hierarchyDef", - hierarchyName - )._throw(); - return index; - }, -/** -* Gets the name of the hierarchy identified by the specified index, or the name of the current hierarchy (in case the index argument is omitted). -* @method hierarchyName -* @param hierarchyIndex {int} The ordinal of the hierarchy for which the name is to be retrieved. When omitted, the name of the current hierarchy is returned. -* @return {string} The name of the hierarchy specified by the argument index, or the name of the current hierarchy if the index argument is omitted. -*/ - hierarchyName: function(index){ - if (_isUnd(index)) index = this._hierarchyIndex; - if (index !== parseInt(index, 10) || - index >= this.numHierarchies - ) - Xmla.Exception._newError( - "INVALID_HIERARCHY", - "Xmla.Dataset.Axis.hierarchyDef", - index - )._throw(); - return this._hierarchyOrder[index]; - }, -/** -* Gets the hierarchy identified by the specified index or hierarchyName, or the current hierarchy (in case the argument is omitted). -* The hierarchy is returned as an object with the following properties: -* In addition, the XML/A specification suggests the following standard properties: -* @method hierarchy -* @param hierarchyIndexOrName {int|string} The ordinal or name of the hierarchy that is to be retrieved. When omitted, the the current hierarchy is returned. -* @return {string} The hierarchy specified by the argument index or name, or the current hierarchy if the argument is omitted. -*/ - hierarchy: function(hierarchyIndexOrName){ - if (_isUnd(hierarchyIndexOrName)) index = this._hierarchyIndex; - var index, hierarchyName, hierarchy; - if (_isNum(hierarchyIndexOrName)) { - if (hierarchyIndexOrName !== parseInt(hierarchyIndexOrName, 10) - || hierarchyIndexOrName >= this.numHierarchies + return tuple; + }, + /** + *

Calls a callback function for each tuple in this Axis object.

+ *

The callback function is passed an object that represents the current tuple. (see getTuple() for a description of the tuple format.)

+ *

The callback may return false to abort iteration. If the callback does not return false, iteration will resume until all tuples are traversed.

+ * @param {function()} callback A function that will be called for each tuple. The tuple is passed as an object as the first argument to the callback. + * @param {object} scope The object that will be used as scope when executing the callback function. If this is undefined or null, the Axis' this pointer will be used. + * @param {object} args Additional data to be passed as the second argument to the callback function. + * @method eachTuple + * @return {boolean} Returns true if all tuples were visited and the callback did not return false. Returns false if the callback returned false and further iteration was aborted. + */ + eachTuple: function(callback, scope, args){ + var mArgs = [null]; + if (!scope) { + scope = this; + } + if (args) { + if (_isArr(args)) { + mArgs.concat(args) + } + else { + mArgs.push(args); + } + } + while (this.hasMoreTuples()){ + mArgs[0] = this.getTuple(); + if (callback.apply(scope, mArgs) === false) { + return false; + } + this.nextTuple(); + } + this._tupleIndex = 0; + this._members = this._getMembers(); + return true; + }, + /** + * Returns the hierarchies of this Axis object. + * The hierarchies are returned as an object. The keys are the hierarchy names; the values are objects representing the hierarchies. + * The hierarchy object has the following properties: + * The properties always contain the intrinsic properties Caption, DisplayInfo, LName, LNum and UName. + * If any additional properties were included (for example, by having a MDX DIMENSION PROPERTIES clause then these will be included as well. + * @method getHierarchies + * @return {array} An object representing the hierarchies contained in this Axis. + **/ + getHierarchies: function(){ + return this._hierarchyDefs; + }, + /** + * Returns the names of the hierarchies of this Axis object. + * @method getHierarchyNames + * @return {array} An array of names of the hierarchies contained in this Axis. + **/ + getHierarchyNames: function(){ + var hierarchyNames = [], i, n = this.numHierarchies; + for (i = 0; i < n; i++) hierarchyNames[i] = this._hierarchyOrder[i]; + return hierarchyNames; + }, + /** + * Gets the number of hierarchies in this axis object. + * @method hierarchyCount + * @return {int} Returns the number of hierarchies in this Axis object. + */ + hierarchyCount: function(){ + return this.numHierarchies; + }, + /** + * Gets the index of the hierarchy identified by the specified name, or the index of the current hierarchy (in case the name argument is omitted). + * @method hierarchyIndex + * @param hierarchyName {string} The name of the hierarchy for which the index is to be retrieved. When omitted, the index of the current hierarchy is returned. + * @return {int} The index of the hierarchy specified by the name passed as argument, or the index of the current hierarchy if the name argument is omitted. + */ + hierarchyIndex: function(hierarchyName){ + if (_isUnd(hierarchyName)) return this._hierarchyIndex; + var index = this._hierarchyIndexes[hierarchyName]; + if (_isUnd(index)) + Xmla.Exception._newError( + "INVALID_HIERARCHY", + "Xmla.Dataset.Axis.hierarchyDef", + hierarchyName + )._throw(); + return index; + }, + /** + * Gets the name of the hierarchy identified by the specified index, or the name of the current hierarchy (in case the index argument is omitted). + * @method hierarchyName + * @param hierarchyIndex {int} The ordinal of the hierarchy for which the name is to be retrieved. When omitted, the name of the current hierarchy is returned. + * @return {string} The name of the hierarchy specified by the argument index, or the name of the current hierarchy if the index argument is omitted. + */ + hierarchyName: function(index){ + if (_isUnd(index)) index = this._hierarchyIndex; + if (index !== parseInt(index, 10) || + index >= this.numHierarchies ) Xmla.Exception._newError( "INVALID_HIERARCHY", "Xmla.Dataset.Axis.hierarchyDef", - hierarchyIndexOrName + index )._throw(); - hierarchyName = this.hierarchyName(hierarchyIndexOrName); - } - else hierarchyName = hierarchyIndexOrName; - hierarchy = this._hierarchyDefs[hierarchyName]; - if (_isUnd(hierarchy)) - Xmla.Exception._newError( - "INVALID_HIERARCHY", - "Xmla.Dataset.Axis.hierarchyDef", - hierarchyName - )._throw(); - return hierarchy; - }, -/** -* Gets the member for the specified hierarchy from the current tuple. The member has the following structure: -*

-* The index and hierarchy properties are non standard and always added by Xmla4js. -* The properties UName, Caption, LName and LNum are defined by the XML/A standard, and should always be present. -* The property DisplayInfo is non-standard, but often available. -* Other properties may be present depending on the specific XML/A provider. -*

-* @method member -* @param hierarchyIndexOrName {int|string} The ordinal or name of the hierarchy from which the member is to be retrieved. When omitted, the the current hierarchy is returned. -* @return {object} The member of the current tuple that belongs to the specified hierarchy, If the argument is omitted the member that belongs current hierarchy is retrieved from the current tuple. -*/ - member: function(hierarchyIndexOrName){ - if (_isUnd(hierarchyIndexOrName)) { - index = this._hierarchyIndex; - } - var index, hierarchyName; - switch(typeof(hierarchyIndexOrName)){ - case "string": - index = this.hierarchyIndex(hierarchyIndexOrName); - hierarchyName = hierarchyIndexOrName; - break; - case "number": - if (hierarchyIndexOrName !== parseInt(hierarchyIndexOrName, 10) || - hierarchyIndexOrName >= this.numHierarchies + return this._hierarchyOrder[index]; + }, + /** + * Gets the hierarchy identified by the specified index or hierarchyName, or the current hierarchy (in case the argument is omitted). + * The hierarchy is returned as an object with the following properties: + * In addition, the XML/A specification suggests the following standard properties: + * @method hierarchy + * @param hierarchyIndexOrName {int|string} The ordinal or name of the hierarchy that is to be retrieved. When omitted, the the current hierarchy is returned. + * @return {string} The hierarchy specified by the argument index or name, or the current hierarchy if the argument is omitted. + */ + hierarchy: function(hierarchyIndexOrName){ + if (_isUnd(hierarchyIndexOrName)) index = this._hierarchyIndex; + var index, hierarchyName, hierarchy; + if (_isNum(hierarchyIndexOrName)) { + if (hierarchyIndexOrName !== parseInt(hierarchyIndexOrName, 10) + || hierarchyIndexOrName >= this.numHierarchies ) Xmla.Exception._newError( "INVALID_HIERARCHY", "Xmla.Dataset.Axis.hierarchyDef", hierarchyIndexOrName )._throw(); - index = hierarchyIndexOrName; - break; - } - return this._member(index); - }, - _member: function(index){ - var memberNode = this._members[index], - childNodes = memberNode.childNodes, - i, n = childNodes.length, - hierarchyName = this.hierarchyName(index), - hierarchyDef = this._hierarchyDefs[hierarchyName], - properties = hierarchyDef.properties, - property, - member = { - index: index, - hierarchy: hierarchyName - }, - el, - valueConverter - ; - for (i = 0; i < n; i++) { - el = childNodes[i]; - if (el.nodeType !== 1) { - continue; + hierarchyName = this.hierarchyName(hierarchyIndexOrName); } - property = properties[el.nodeName]; - if (!property) { - continue; + else hierarchyName = hierarchyIndexOrName; + hierarchy = this._hierarchyDefs[hierarchyName]; + if (_isUnd(hierarchy)) + Xmla.Exception._newError( + "INVALID_HIERARCHY", + "Xmla.Dataset.Axis.hierarchyDef", + hierarchyName + )._throw(); + return hierarchy; + }, + /** + * Gets the member for the specified hierarchy from the current tuple. The member has the following structure: + *

+ * The index and hierarchy properties are non standard and always added by Xmla4js. + * The properties UName, Caption, LName and LNum are defined by the XML/A standard, and should always be present. + * The property DisplayInfo is non-standard, but often available. + * Other properties may be present depending on the specific XML/A provider. + *

+ * @method member + * @param hierarchyIndexOrName {int|string} The ordinal or name of the hierarchy from which the member is to be retrieved. When omitted, the the current hierarchy is returned. + * @return {object} The member of the current tuple that belongs to the specified hierarchy, If the argument is omitted the member that belongs current hierarchy is retrieved from the current tuple. + */ + member: function(hierarchyIndexOrName){ + if (_isUnd(hierarchyIndexOrName)) { + index = this._hierarchyIndex; } - member[property.propertyName || property.name] = property.converter(_getElementText(el)); - } - return member; - }, -/** -* Check if the member has the specified property. -* XML/A defines these standard properties: -* The XML/A provider may return specific additional properties. -* @method hasMemberProperty -* @param propertyName {string} The name of the property to check for. -* @return {boolean} returns true if the current member has the specified property, false if it doesn't. -*/ - hasMemberProperty: function(propertyName) { - return !_isUnd(this._memberProperties[propertyName]); - }, -/** -* Gets the current tuple as an array of members. -* For a description of the structure of the member elements, see member(). -* @method readAsArray -* @param array {array} An existing array to store the members in. If omitted, a new array is returned. -* @return {array} An array of members that represents the current tuple. -*/ - readAsArray: function(array){ - if (!array) array = []; - var i, n = this.numHierarchies; - for (i = 0; i < n; i++) array[i] = this._member(i); - return array; - }, -/** -* Gets the current tuple as an object. -* The object's keys are the hierarchy names, and the members of the current tuple are used as values for the keys. -* For a description of the structure of the member elements, see member(). -* @method readAsObject -* @param object {object} An existing object to store the tuple data in. If omitted, a new object is returned. -* @return {object} An object that represents the current tuple. -*/ - readAsObject: function(object){ - if (!object) object = {}; - var i, n = this.numHierarchies; - for (i = 0; i < n; i++) object[this._hierarchyOrder[i]] = this._member(i); - return object; - }, -/** -* Gets the current tuple as an array of members and advances the internal tuple pointer. -* For a description of the structure of the member elements, see member(). -* @method fetchAsArray -* @param array {array} An existing array to store the members in. If omitted, a new array is returned. -* @return {array|false} An array of members that represents the current tuple, or false if there are no more tuples. -*/ - fetchAsArray: function(array){ - if (this.hasMoreTuples()) { - array = this.readAsArray(array); - this.nextTuple(); - } - else array = false; - return array; - }, -/** -* Gets the current tuple as an object and advances the current tuple pointer. -* The object's keys are the hierarchy names, and the members of the current tuple are used as values for the keys. -* For a description of the structure of the member elements, see member(). -* @method fetchAsObject -* @param object {object} An existing object to store the tuple data in. If omitted, a new object is returned. -* @return {object} An object that represents the current tuple. -*/ - fetchAsObject: function(object){ - if (this.hasMoreTuples(object)){ - object = this.readAsObject(); - this.nextTuple(); + var index, hierarchyName; + switch(typeof(hierarchyIndexOrName)){ + case "string": + index = this.hierarchyIndex(hierarchyIndexOrName); + hierarchyName = hierarchyIndexOrName; + break; + case "number": + if (hierarchyIndexOrName !== parseInt(hierarchyIndexOrName, 10) || + hierarchyIndexOrName >= this.numHierarchies + ) + Xmla.Exception._newError( + "INVALID_HIERARCHY", + "Xmla.Dataset.Axis.hierarchyDef", + hierarchyIndexOrName + )._throw(); + index = hierarchyIndexOrName; + break; + } + return this._member(index); + }, + _member: function(index){ + var memberNode = this._members[index], + childNodes = memberNode.childNodes, + i, n = childNodes.length, + hierarchyName = this.hierarchyName(index), + hierarchyDef = this._hierarchyDefs[hierarchyName], + properties = hierarchyDef.properties, + property, + member = { + index: index, + hierarchy: hierarchyName + }, + el, + valueConverter + ; + for (i = 0; i < n; i++) { + el = childNodes[i]; + if (el.nodeType !== 1) { + continue; + } + property = properties[el.nodeName]; + if (!property) { + continue; + } + member[property.propertyName || property.name] = property.converter(_getElementText(el)); + } + return member; + }, + /** + * Check if the member has the specified property. + * XML/A defines these standard properties: + * The XML/A provider may return specific additional properties. + * @method hasMemberProperty + * @param propertyName {string} The name of the property to check for. + * @return {boolean} returns true if the current member has the specified property, false if it doesn't. + */ + hasMemberProperty: function(propertyName) { + return !_isUnd(this._memberProperties[propertyName]); + }, + /** + * Gets the current tuple as an array of members. + * For a description of the structure of the member elements, see member(). + * @method readAsArray + * @param array {array} An existing array to store the members in. If omitted, a new array is returned. + * @return {array} An array of members that represents the current tuple. + */ + readAsArray: function(array){ + if (!array) array = []; + var i, n = this.numHierarchies; + for (i = 0; i < n; i++) array[i] = this._member(i); + return array; + }, + /** + * Gets the current tuple as an object. + * The object's keys are the hierarchy names, and the members of the current tuple are used as values for the keys. + * For a description of the structure of the member elements, see member(). + * @method readAsObject + * @param object {object} An existing object to store the tuple data in. If omitted, a new object is returned. + * @return {object} An object that represents the current tuple. + */ + readAsObject: function(object){ + if (!object) object = {}; + var i, n = this.numHierarchies; + for (i = 0; i < n; i++) object[this._hierarchyOrder[i]] = this._member(i); + return object; + }, + /** + * Gets the current tuple as an array of members and advances the internal tuple pointer. + * For a description of the structure of the member elements, see member(). + * @method fetchAsArray + * @param array {array} An existing array to store the members in. If omitted, a new array is returned. + * @return {array|false} An array of members that represents the current tuple, or false if there are no more tuples. + */ + fetchAsArray: function(array){ + if (this.hasMoreTuples()) { + array = this.readAsArray(array); + this.nextTuple(); + } + else array = false; + return array; + }, + /** + * Gets the current tuple as an object and advances the current tuple pointer. + * The object's keys are the hierarchy names, and the members of the current tuple are used as values for the keys. + * For a description of the structure of the member elements, see member(). + * @method fetchAsObject + * @param object {object} An existing object to store the tuple data in. If omitted, a new object is returned. + * @return {object} An object that represents the current tuple. + */ + fetchAsObject: function(object){ + if (this.hasMoreTuples(object)){ + object = this.readAsObject(); + this.nextTuple(); + } + else object = false; + return object; + }, + /** + * Fetches all tuples and returns them as an array of arrays. + * Each element of the returned array is an array of member objects. + * For a description of the structure of the member elements, see member(). + * @method fetchAllAsArray + * @param rows {array} An existing array to store the tuples in. If omitted, a new array is returned. + * @return {[[array]]} An array of arrays representing all tuples that belong to this axis. + **/ + fetchAllAsArray: function(rows){ + var row; + if (!rows) rows = []; + while((row = this.fetchAsArray())) rows.push(row); + this.reset(); + return rows; + }, + /** + * Fetches all tuples and returns them as an array of objects. + * Each element of the returned array is a tuple object. + * The object's keys are the hierarchy names, and the members of the current tuple are used as values for the keys. + * For a description of the structure of the member elements, see member(). + * @method fetchAllAsObject + * @param rows {array} An existing array to store the tuples in. If omitted, a new array is returned. + * @return {[[object]]} An array of arrays representing all tuples that belong to this axis. + **/ + fetchAllAsObject: function(rows){ + var row; + if (!rows) rows = []; + while((row = this.fetchAsObject())) rows.push(row); + this.reset(); + return rows; } - else object = false; - return object; - }, -/** -* Fetches all tuples and returns them as an array of arrays. -* Each element of the returned array is an array of member objects. -* For a description of the structure of the member elements, see member(). -* @method fetchAllAsArray -* @param rows {array} An existing array to store the tuples in. If omitted, a new array is returned. -* @return {[[array]]} An array of arrays representing all tuples that belong to this axis. -**/ - fetchAllAsArray: function(rows){ - var row; - if (!rows) rows = []; - while((row = this.fetchAsArray())) rows.push(row); - this.reset(); - return rows; - }, -/** -* Fetches all tuples and returns them as an array of objects. -* Each element of the returned array is a tuple object. -* The object's keys are the hierarchy names, and the members of the current tuple are used as values for the keys. -* For a description of the structure of the member elements, see member(). -* @method fetchAllAsObject -* @param rows {array} An existing array to store the tuples in. If omitted, a new array is returned. -* @return {[[object]]} An array of arrays representing all tuples that belong to this axis. -**/ - fetchAllAsObject: function(rows){ - var row; - if (!rows) rows = []; - while((row = this.fetchAsObject())) rows.push(row); - this.reset(); - return rows; } -} - -/** -*

-* This class implements a Cellset object. -*

-*

-* You do not need to instantiate objects of this class yourself. -* Rather, the Xmla.Dataset class creates instances of this class to represent the cells (the value of the measures) of an MDX query. -* (see getCellset().) -* -* @class Xmla.Dataset.Cellset -* @constructor -*/ -Xmla.Dataset.Cellset = function(dataset){ - this._dataset = dataset; - this._initCellset(); - return this; -} - -Xmla.Dataset.Cellset.prototype = { - _dataset: null, - _cellNodes: null, - _cellCount: null, - _cellNode: null, - _cellProperties: null, - _idx: null, - _cellOrd: null, - _initCellset: function(){ - var root = this._dataset._root, - cellSchema, cellSchemaElements, numCellSchemaElements, cellSchemaElement, - cellInfoNodes, cellInfoNode, type, - propertyNodes, propertyNode, propertyNodeTagName, numPropertyNodes, i, j - ; - cellSchema = _getComplexType(root, "CellData"); - if (!cellSchema) - Xmla.Exception._newError( - "ERROR_PARSING_RESPONSE", - "Xmla.Dataset.Cellset", - root - )._throw(); - cellSchemaElements = _getElementsByTagNameNS( - cellSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "element" - ); - numCellSchemaElements = cellSchemaElements.length; - cellInfoNodes = _getElementsByTagNameNS( - root, _xmlnsDataset, "", "CellInfo" - ); - if (!cellInfoNodes || cellInfoNodes.length===0) - Xmla.Exception._newError( - "ERROR_PARSING_RESPONSE", - "Xmla.Rowset", - root - )._throw(); - - cellInfoNode = cellInfoNodes[0]; - propertyNodes = _getElementsByTagNameNS( - cellInfoNode, _xmlnsDataset, "", "*" - ); - this._cellProperties = {}; - //examine cell property info so we can parse them - numPropertyNodes = propertyNodes.length; - var me = this; - var makePropertyGetter = function(propertyNodeTagName){ - me["cell" + propertyNodeTagName] = function(){ - return this.cellProperty(propertyNodeTagName); - }; - }; - for(i = 0; i < numPropertyNodes; i++) { - propertyNode = propertyNodes[i]; - propertyNodeTagName = propertyNode.nodeName; - //find the xsd:element node that describes this property - for (j = 0; j < numCellSchemaElements; j++) { - cellSchemaElement = cellSchemaElements[j]; - if (_getAttribute(cellSchemaElement, "name") !== propertyNodeTagName) { + + /** + *

+ * This class implements a Cellset object. + *

+ *

+ * You do not need to instantiate objects of this class yourself. + * Rather, the Xmla.Dataset class creates instances of this class to represent the cells (the value of the measures) of an MDX query. + * (see getCellset().) + * + * @class Xmla.Dataset.Cellset + * @constructor + */ + Xmla.Dataset.Cellset = function(dataset){ + this._dataset = dataset; + this._initCellset(); + return this; + } + + Xmla.Dataset.Cellset.prototype = { + _dataset: null, + _cellNodes: null, + _cellCount: null, + _cellNode: null, + _cellProperties: null, + _idx: null, + _cellOrd: null, + _initCellset: function(){ + var root = this._dataset._root, + cellSchema, cellSchemaElements, numCellSchemaElements, cellSchemaElement, + cellInfoNodes, cellInfoNode, type, + propertyNodes, propertyNode, propertyNodeTagName, numPropertyNodes, i, j + ; + cellSchema = _getComplexType(root, "CellData"); + if (!cellSchema) + Xmla.Exception._newError( + "ERROR_PARSING_RESPONSE", + "Xmla.Dataset.Cellset", + root + )._throw(); + cellSchemaElements = _getElementsByTagNameNS( + cellSchema, _xmlnsSchema, _xmlnsSchemaPrefix, "element" + ); + numCellSchemaElements = cellSchemaElements.length; + cellInfoNodes = _getElementsByTagNameNS( + root, _xmlnsDataset, "", "CellInfo" + ); + if (!cellInfoNodes || cellInfoNodes.length===0) + Xmla.Exception._newError( + "ERROR_PARSING_RESPONSE", + "Xmla.Rowset", + root + )._throw(); + + cellInfoNode = cellInfoNodes[0]; + propertyNodes = _getElementsByTagNameNS( + cellInfoNode, _xmlnsDataset, "", "*" + ); + this._cellProperties = {}; + //examine cell property info so we can parse them + numPropertyNodes = propertyNodes.length; + var me = this; + var makePropertyGetter = function(propertyNodeTagName){ + me["cell" + propertyNodeTagName] = function(){ + return this.cellProperty(propertyNodeTagName); + }; + }; + for(i = 0; i < numPropertyNodes; i++) { + propertyNode = propertyNodes[i]; + propertyNodeTagName = propertyNode.nodeName; + //find the xsd:element node that describes this property + for (j = 0; j < numCellSchemaElements; j++) { + cellSchemaElement = cellSchemaElements[j]; + if (_getAttribute(cellSchemaElement, "name") !== propertyNodeTagName) { + continue; + } + type = _getAttribute(cellSchemaElement, "type"); + this._cellProperties[propertyNodeTagName] = _typeConverterMap[type]; + //this["cell" + propertyNodeTagName] = new Function("return this.cellProperty(\"" + propertyNodeTagName + "\")"); + makePropertyGetter(propertyNodeTagName); + break; + } + //extra: if the schema doesn't explicitly define this property, we somehow have to + if (!this._cellProperties[propertyNodeTagName]) { + type = _getAttribute(propertyNode, "type"); + if (!type) { + type = (propertyNodeTagName === "Value") ? "xs:decimal" : "xs:string"; + } + this._cellProperties[propertyNodeTagName] = _typeConverterMap[type]; + //this["cell" + propertyNodeTagName] = new Function("return this.cellProperty(\"" + propertyNodeTagName + "\")"); + makePropertyGetter(propertyNodeTagName); + } + } + this._cellNodes = _getElementsByTagNameNS( + root, _xmlnsDataset, "", "Cell" + ); + this._cellCount = this._cellNodes.length; + this.reset(); + }, + _getCellNode: function(index){ + //console.debug(index); + if (!_isUnd(index)) { + this._idx = index; + } + this._cellNode = this._cellNodes[this._idx]; + this._cellOrd = this._getCellOrdinal(this._cellNode); + }, + _getCellOrdinal: function(node){ + return parseInt(_getAttribute(node, "CellOrdinal"), 10); + }, + /** + * Returns the number of cells contained in this cellset. + * This is the number of cells that is actually present in the cellset - not the number of logical cells. + * The nuber of logical cells can be be calculated by multiplying the tuple counts of all axes of the data set. + * The XML/A provider will typically not return empty cells, hence, the cellCount may be less than the logical cell count. + * @method cellCount + * @return {int} The number of cells in this cellset. + */ + cellCount: function() { + return this._cellNodes.length; + }, + /** + * Resets the internal cell pointer to the argument, or to 0 if the argument is omitted. + * Normally, you shouldn't have to call this method yourself. + * @method reset + * @param idx {int} + */ + reset: function(idx){ + this._idx = idx ? idx : 0; + if (this.hasMoreCells()) { + this._getCellNode(); + } + }, + /** + * Check if there are cells to iterate through. + * @method hasMoreCells + * @return {boolean} true if there are more cells to iterate, false if there are no more cells to iterate. + */ + hasMoreCells: function(){ + return this._idx < this._cellCount; + }, + /** + * Advance to the next (physical) cell. + * Note that this method may appear to be skipping cells. This happens when the XML/A provider omits empty cells in the response. + * @method nextCell + * @return {int} returns the ordinal of the next cell, or -1 if there was no next cell. + */ + nextCell: function(){ + this._idx += 1; + if (this.hasMoreCells()) { + this._getCellNode(); + return this._cellOrd; + } + else { + this._idx = 0; + return -1; + } + }, + /** + * Returns the internal cell pointer. This is the fysical cell pointer. + * To get the logical cell pointer, see cellOrdinal() + * @method curr + * @return {int} returns the internal cell pointer. + */ + curr: function(){ + return this._idx; + }, + /** + * Check if the cell has the specified property. + * XML/A defines these standard properties:

+ * Whether all these properties are returned depends on the XML/A provider and on the query. + * The XML/A provider may return specific additional properties. + * @method hasCellProperty + * @param propertyName {string} The name of the property to check for. + * @return {boolean} returns true if the current cell has the specified property, false if it doesn't. + */ + hasCellProperty: function(propertyName) { + return !_isUnd(this._cellProperties[propertyName]); + }, + /** + * Return the value of the current property of the current cell. + * XML/A defines these standard properties: + * Whether all these properties are returned depends on the XML/A provider and on the query. + * The XML/A provider may return specific additional properties. + * @method cellProperty + * @param propertyName {string} The name of the property to retrieve. + * @return {mixed} returns the value of the specified property of the current cell. + */ + cellProperty: function(propertyName){ + var text, type, valueConverter, + valueEl = _getElementsByTagNameNS( + this._cellNode, _xmlnsDataset, "", propertyName + ), value; + if (valueEl.length) { + valueEl = valueEl[0]; + text = _getElementValue(valueEl); + valueConverter = this._cellProperties[propertyName]; + if (!valueConverter) { + type = _getAttributeNS( + valueEl, + _xmlnsSchemaInstance, + _xmlnsSchemaInstancePrefix, + "type" + ); + valueConverter = _getValueConverter(type); + } + value = valueConverter(text); + } + else { + value = null; + } + return value; + }, + /** + * Returns the ordinal number of the current cell. + * The ordinal is the logical cell pointer, which may be different than the physical cell pointer. + * To get the physical cell pointer, see curr() + * @method cellOrdinal + * @return {int} returns the logical cell pointer. + */ + cellOrdinal: function() { + return this._cellOrd; + }, + _readCell: function(node, object){ + var p, cellProp, cellProperty; + for (p in this._cellProperties){ + cellProp = _getElementsByTagNameNS( + node, _xmlnsDataset, "", p + )[0]; + if (!cellProp) { continue; } - type = _getAttribute(cellSchemaElement, "type"); - this._cellProperties[propertyNodeTagName] = _typeConverterMap[type]; - //this["cell" + propertyNodeTagName] = new Function("return this.cellProperty(\"" + propertyNodeTagName + "\")"); - makePropertyGetter(propertyNodeTagName); - break; + cellProperty = this._cellProperties[p]; + if (cellProperty) { + object[p] = cellProperty(_getElementText(cellProp)); + } + else + if (p === "Value") { + object[p] = _getElementValue(cellProp); + } + else { + object[p] = _getElementText(cellProp); + } + } + object.ordinal = this._getCellOrdinal(node); + return object; + }, + /** + * Reads the current cell into the specified object. + * @method readCell + * @param {object} object An existing object to use for the current cell. If omitted, a new object will be created. + * @return {object} An object that represents the current cell. + */ + readCell: function(object) { + if (!object) { + object = {}; } - //extra: if the schema doesn't explicitly define this property, we somehow have to - if (!this._cellProperties[propertyNodeTagName]) { - type = _getAttribute(propertyNode, "type"); - if (!type) { - type = (propertyNodeTagName === "Value") ? "xs:decimal" : "xs:string"; + return this._readCell(this._cellNode, object); + }, + /** + * Iterate through each cell. + * @method eachCell + * @param {function()} callback + * @param {object} scope + * @param {object} args + * @return {boolean} + */ + eachCell: function(callback, scope, args) { + var mArgs = [null]; + if (!scope) { + scope = this; + } + if (args) { + if (!_isArr(args)) { + args = [args]; + } + mArgs = mArgs.concat(args); + } + var ord; + while (ord !== -1 && this.hasMoreCells()){ + ord = this.nextCell(); + mArgs[0] = this.readCell(); + if (callback.apply(scope, mArgs)===false) { + return false; } - this._cellProperties[propertyNodeTagName] = _typeConverterMap[type]; - //this["cell" + propertyNodeTagName] = new Function("return this.cellProperty(\"" + propertyNodeTagName + "\")"); - makePropertyGetter(propertyNodeTagName); } - } - this._cellNodes = _getElementsByTagNameNS( - root, _xmlnsDataset, "", "Cell" - ); - this._cellCount = this._cellNodes.length; - this.reset(); - }, - _getCellNode: function(index){ - //console.debug(index); - if (!_isUnd(index)) { - this._idx = index; - } - this._cellNode = this._cellNodes[this._idx]; - this._cellOrd = this._getCellOrdinal(this._cellNode); - }, - _getCellOrdinal: function(node){ - return parseInt(_getAttribute(node, "CellOrdinal"), 10); - }, -/** -* Returns the number of cells contained in this cellset. -* This is the number of cells that is actually present in the cellset - not the number of logical cells. -* The nuber of logical cells can be be calculated by multiplying the tuple counts of all axes of the data set. -* The XML/A provider will typically not return empty cells, hence, the cellCount may be less than the logical cell count. -* @method cellCount -* @return {int} The number of cells in this cellset. -*/ - cellCount: function() { - return this._cellNodes.length; - }, -/** -* Resets the internal cell pointer to the argument, or to 0 if the argument is omitted. -* Normally, you shouldn't have to call this method yourself. -* @method reset -* @param idx {int} -*/ - reset: function(idx){ - this._idx = idx ? idx : 0; - if (this.hasMoreCells()) { - this._getCellNode(); - } - }, -/** -* Check if there are cells to iterate through. -* @method hasMoreCells -* @return {boolean} true if there are more cells to iterate, false if there are no more cells to iterate. -*/ - hasMoreCells: function(){ - return this._idx < this._cellCount; - }, -/** -* Advance to the next (physical) cell. -* Note that this method may appear to be skipping cells. This happens when the XML/A provider omits empty cells in the response. -* @method nextCell -* @return {int} returns the ordinal of the next cell, or -1 if there was no next cell. -*/ - nextCell: function(){ - this._idx += 1; - if (this.hasMoreCells()) { - this._getCellNode(); - return this._cellOrd; - } - else { this._idx = 0; - return -1; - } - }, -/** -* Returns the internal cell pointer. This is the fysical cell pointer. -* To get the logical cell pointer, see cellOrdinal() -* @method curr -* @return {int} returns the internal cell pointer. -*/ - curr: function(){ - return this._idx; - }, -/** -* Check if the cell has the specified property. -* XML/A defines these standard properties: -* Whether all these properties are returned depends on the XML/A provider and on the query. -* The XML/A provider may return specific additional properties. -* @method hasCellProperty -* @param propertyName {string} The name of the property to check for. -* @return {boolean} returns true if the current cell has the specified property, false if it doesn't. -*/ - hasCellProperty: function(propertyName) { - return !_isUnd(this._cellProperties[propertyName]); - }, -/** -* Return the value of the current property of the current cell. -* XML/A defines these standard properties: -* Whether all these properties are returned depends on the XML/A provider and on the query. -* The XML/A provider may return specific additional properties. -* @method cellProperty -* @param propertyName {string} The name of the property to retrieve. -* @return {mixed} returns the value of the specified property of the current cell. -*/ - cellProperty: function(propertyName){ - var text, type, valueConverter, - valueEl = _getElementsByTagNameNS( - this._cellNode, _xmlnsDataset, "", propertyName - ), value; - if (valueEl.length) { - valueEl = valueEl[0]; - text = _getElementValue(valueEl); - valueConverter = this._cellProperties[propertyName]; - if (!valueConverter) { - type = _getAttributeNS( - valueEl, - _xmlnsSchemaInstance, - _xmlnsSchemaInstancePrefix, - "type" - ); - valueConverter = _getValueConverter(type); + return true; + }, + /** + * Iterate through each cell and return them all as a object by cell ordinal. + * @method fetchAllAsObject + * @return {object} + */ + fetchAllAsObject: function(){ + var cell, cells = {}, i = 0, count = this._cellCount; + for (i = 0; i < count; i++){ + cell = this.readCell(); + cells[cell.ordinal] = cell; + this.nextCell(); } - value = valueConverter(text); - } - else { - value = null; - } - return value; - }, -/** -* Returns the ordinal number of the current cell. -* The ordinal is the logical cell pointer, which may be different than the physical cell pointer. -* To get the physical cell pointer, see curr() -* @method cellOrdinal -* @return {int} returns the logical cell pointer. -*/ - cellOrdinal: function() { - return this._cellOrd; - }, - _readCell: function(node, object){ - var p, cellProp, cellProperty; - for (p in this._cellProperties){ - cellProp = _getElementsByTagNameNS( - node, _xmlnsDataset, "", p - )[0]; - if (!cellProp) { - continue; + return cells; + }, + /** + * Get a cell by its physical index. + * This method should typically not be called by clients. + * Instead, they should use getByOrdinal() + * @method getByIndex + * @param {int} index - the physical index of the cell within the cellset. + * @param {object} object - optional. An object to copy the properties of the specified cell to. If omitted, a new object will be returned instead. + * @return {object} An object that represents the cell. + */ + getByIndex: function(index, object) { + this._getCellNode(index); + return this.readCell(object); + }, + /** + * Get a cell by its logical index. + * @method getByOrdinal + * @param {int} ordinal - the ordinal number of the cell to retrieve. + * @param {object} object - optional. An object to copy the properties of the specified cell to. If omitted, a new object will be returned instead. + * @return {object} An object that represents the cell. + */ + getByOrdinal: function(ordinal, object) { + var node, ord, idx, lastIndex = this.cellCount() - 1; + idx = ordinal > lastIndex ? lastIndex : ordinal; + while(true) { + node = this._cellNodes[idx]; + ord = this._getCellOrdinal(node); + if (ord === ordinal) return this.getByIndex(idx, object); + else + if (ord > ordinal) idx--; + else return null; + } + }, + /** + * Get the physical cell index for the specified ordinal number. + * This method is useful to calculate boundaries to retrieve a range of cells. + * @method indexForOrdinal + * @param {int} ordinal - the ordinal number for which the index shoul dbe returned + * @return {int} The physical index. + */ + indexForOrdinal: function(ordinal){ + var cellNodes = this._cellNodes, + n = cellNodes.length, + index = Math.min(ordinal, n-1), + cellOrdinal, node + ; + while(index >= 0) { + //get the node at the current index + node = cellNodes[index]; + cellOrdinal = this._getCellOrdinal(node); + if (cellOrdinal === ordinal) { + return index; + } + else + if (cellOrdinal > ordinal) { + index--; + } + else { + return -1; + } } - cellProperty = this._cellProperties[p]; - if (cellProperty) { - object[p] = cellProperty(_getElementText(cellProp)); + return -1; + }, + /** + * Get a range of cells that fits the specified ordinals. + * This method is useful to grab a slice of cells for a subset of the axes. + * (You can use cellOrdinalForTupleIndexes to calculate ordinals in terms of tuple indexes.) + * The returned range only contains cells that actually exist so the ordinal of adjacent cells may have gaps, + * @method fetchRangeAsArray + * @param {int} from - the ordinal number indicating the start of the range + * @param {int} to - the ordinal number indicating the end of the range + * @return {[object]} - An array of cells that fit the specified range. + */ + fetchRangeAsArray: function(from, to){ + var range = [], cellNodes = this._cellNodes, n = cellNodes.length; + if (n === 0) { + return range; } - else - if (p === "Value") { - object[p] = _getElementValue(cellProp); + + var cellNode, ordinal; + if (_isUnd(to) || to === -1) { + to = this._getCellOrdinal(cellNodes[n-1]); } - else { - object[p] = _getElementText(cellProp); + if (_isUnd(from) || from === -1) { + from = this._getCellOrdinal(cellNodes[0]); } - } - object.ordinal = this._getCellOrdinal(node); - return object; - }, -/** - * Reads the current cell into the specified object. -* @method readCell -* @param {object} object An existing object to use for the current cell. If omitted, a new object will be created. -* @return {object} An object that represents the current cell. -*/ - readCell: function(object) { - if (!object) { - object = {}; - } - return this._readCell(this._cellNode, object); - }, -/** - * Iterate through each cell. -* @method eachCell -* @param {function()} callback -* @param {object} scope -* @param {object} args -* @return {boolean} -*/ - eachCell: function(callback, scope, args) { - var mArgs = [null]; - if (!scope) { - scope = this; - } - if (args) { - if (!_isArr(args)) { - args = [args]; + + //start at to (or at end of array of cells in case empty cells exist) + var toIndex = Math.min(to, n - 1); + while (toIndex >= 0) { + cellNode = cellNodes[toIndex]; + ordinal = this._getCellOrdinal(cellNode); + if (ordinal <= to) { + break; + } + toIndex -= 1; } - mArgs = mArgs.concat(args); - } - var ord; - while (ord !== -1 && this.hasMoreCells()){ - ord = this.nextCell(); - mArgs[0] = this.readCell(); - if (callback.apply(scope, mArgs)===false) { - return false; + + if (toIndex === -1) { + //Would be very strange to arrive here. + return range; } - } - this._idx = 0; - return true; - }, -/** - * Iterate through each cell and return them all as a object by cell ordinal. -* @method fetchAllAsObject -* @return {object} -*/ - fetchAllAsObject: function(){ - var cell, cells = {}, i = 0, count = this._cellCount; - for (i = 0; i < count; i++){ - cell = this.readCell(); - cells[cell.ordinal] = cell; - this.nextCell(); - } - return cells; - }, -/** - * Get a cell by its physical index. - * This method should typically not be called by clients. - * Instead, they should use getByOrdinal() -* @method getByIndex -* @param {int} index - the physical index of the cell within the cellset. -* @param {object} object - optional. An object to copy the properties of the specified cell to. If omitted, a new object will be returned instead. -* @return {object} An object that represents the cell. -*/ - getByIndex: function(index, object) { - this._getCellNode(index); - return this.readCell(object); - }, -/** - * Get a cell by its logical index. -* @method getByOrdinal -* @param {int} ordinal - the ordinal number of the cell to retrieve. -* @param {object} object - optional. An object to copy the properties of the specified cell to. If omitted, a new object will be returned instead. -* @return {object} An object that represents the cell. -*/ - getByOrdinal: function(ordinal, object) { - var node, ord, idx, lastIndex = this.cellCount() - 1; - idx = ordinal > lastIndex ? lastIndex : ordinal; - while(true) { - node = this._cellNodes[idx]; - ord = this._getCellOrdinal(node); - if (ord === ordinal) return this.getByIndex(idx, object); - else - if (ord > ordinal) idx--; - else return null; - } - }, -/** - * Get the physical cell index for the specified ordinal number. - * This method is useful to calculate boundaries to retrieve a range of cells. - * @method indexForOrdinal - * @param {int} ordinal - the ordinal number for which the index shoul dbe returned - * @return {int} The physical index. - */ - indexForOrdinal: function(ordinal){ - var cellNodes = this._cellNodes, - n = cellNodes.length, - index = Math.min(ordinal, n-1), - cellOrdinal, node - ; - while(index >= 0) { - //get the node at the current index - node = cellNodes[index]; - cellOrdinal = this._getCellOrdinal(node); - if (cellOrdinal === ordinal) { - return index; + + if (ordinal < from) { + //The ordinal closest to "to" lies before "from" -> no cells are in range. + return range; } - else - if (cellOrdinal > ordinal) { - index--; + + var fromIndex = Math.min(toIndex, from); + while (fromIndex >= 0) { + cellNode = cellNodes[fromIndex]; + ordinal = this._getCellOrdinal(cellNode); + if (ordinal <= from) { + if (ordinal < from) { + fromIndex += 1; + } + break; + } + fromIndex -= 1; } - else { - return -1; + + if (fromIndex === -1) { + fromIndex = 0; } - } - return -1; - }, -/** - * Get a range of cells that fits the specified ordinals. - * This method is useful to grab a slice of cells for a subset of the axes. - * (You can use cellOrdinalForTupleIndexes to calculate ordinals in terms of tuple indexes.) - * The returned range only contains cells that actually exist so the ordinal of adjacent cells may have gaps, - * @method fetchRangeAsArray - * @param {int} from - the ordinal number indicating the start of the range - * @param {int} to - the ordinal number indicating the end of the range - * @return {[object]} - An array of cells that fit the specified range. - */ - fetchRangeAsArray: function(from, to){ - var range = [], cellNodes = this._cellNodes, n = cellNodes.length; - if (n === 0) { - return range; - } - - var cellNode, ordinal; - if (_isUnd(to) || to === -1) { - to = this._getCellOrdinal(cellNodes[n-1]); - } - if (_isUnd(from) || from === -1) { - from = this._getCellOrdinal(cellNodes[0]); - } - - //start at to (or at end of array of cells in case empty cells exist) - var toIndex = Math.min(to, n - 1); - while (toIndex >= 0) { - cellNode = cellNodes[toIndex]; - ordinal = this._getCellOrdinal(cellNode); - if (ordinal <= to) { - break; - } - toIndex -= 1; - } - - if (toIndex === -1) { - //Would be very strange to arrive here. - return range; - } - - if (ordinal < from) { - //The ordinal closest to "to" lies before "from" -> no cells are in range. - return range; - } - - var fromIndex = Math.min(toIndex, from); - while (fromIndex >= 0) { - cellNode = cellNodes[fromIndex]; - ordinal = this._getCellOrdinal(cellNode); - if (ordinal <= from) { - if (ordinal < from) { - fromIndex += 1; + + var index; + for (index = fromIndex; index <= toIndex; index++) { + cellNode = cellNodes[index]; + range.push(this._readCell(cellNode, {})); } - break; - } - fromIndex -= 1; - } - - if (fromIndex === -1) { - fromIndex = 0; - } - - var index; - for (index = fromIndex; index <= toIndex; index++) { - cellNode = cellNodes[index]; - range.push(this._readCell(cellNode, {})); + return range; + }, + /** + * Calculate the ordinal based on the specified tuple indexes. + * @method cellOrdinalForTupleIndexes + * @param {int...} tuple index - a variable list of integer arguments. Arguments represent the index of a tuple on the query axes. Tuple indexes should be specified by descending order of axes. For example, if you have a DataSet with 2 Axes, pass the row tuple index as the first argument, and the column tuple index as the last argument. + * @return {int} The ordinal number for this combination of tuple indexes. This return value can be used as argument for getByOrdinal() + */ + cellOrdinalForTupleIndexes: function() { + return this._dataset.cellOrdinalForTupleIndexes.apply(this._dataset, arguments); + }, + /** + * Get the cell corresponding to the specified tuple indexes. + * @method getByTupleIndexes + * @param {int...} ordinal + * @return {object} + */ + getByTupleIndexes: function() { + return this.getByOrdinal(this.cellOrdinalForTupleIndexes.apply(this, arguments)); + }, + /** + * Close this cellset. + * @method close + */ + close: function(){ + this._dataset = null; + this._cellNodes = null; + this._cellNode = null; } - return range; - }, -/** - * Calculate the ordinal based on the specified tuple indexes. -* @method cellOrdinalForTupleIndexes -* @param {int...} tuple index - a variable list of integer arguments. Arguments represent the index of a tuple on the query axes. Tuple indexes should be specified by descending order of axes. For example, if you have a DataSet with 2 Axes, pass the row tuple index as the first argument, and the column tuple index as the last argument. -* @return {int} The ordinal number for this combination of tuple indexes. This return value can be used as argument for getByOrdinal() -*/ - cellOrdinalForTupleIndexes: function() { - return this._dataset.cellOrdinalForTupleIndexes.apply(this._dataset, arguments); - }, -/** - * Get the cell corresponding to the specified tuple indexes. -* @method getByTupleIndexes -* @param {int...} ordinal -* @return {object} -*/ - getByTupleIndexes: function() { - return this.getByOrdinal(this.cellOrdinalForTupleIndexes.apply(this, arguments)); - }, -/** - * Close this cellset. -* @method close -*/ - close: function(){ - this._dataset = null; - this._cellNodes = null; - this._cellNode = null; } -} - - -/** -*

-* This class is used to indicate an runtime errors occurring in any of the methods of the xmla4js classes. -*

-*

-* You do not need to instantiate objects of this class yourself. -* Rather, instances of this class are created and thrown at runtime whenever an error occurs. -* The purpose is to provide a clean and clear way for applications that use xmla4js to recognize and handle Xmla4js specific runtime errors. -*

-*

-* To handle Xmla4js errors, you can use a try...catch block like this: -*

-
- try {
-     ...general xmla4js work...
- } catch (exception) {
-     if (exception instanceof Xmla.Exception) {
-         ...use exception.code, exception.message and exception.data to handle the exception.
-     } else {
-         ...handle other errors...
-     }
- }
-
-* -* @class Xmla.Exception -* @constructor -*/ -Xmla.Exception = function(type, code, message, helpfile, source, data, args, detail, actor){ - this.type = type; - this.code = code; - this.message = message; - this.source = source; - this.helpfile = helpfile; - this.data = data; - this.args = args; - this.detail = detail; - this.actor = actor; - return this; -}; - -/** -* Can appear as value for the type property of instances of the Xmla.Exception class, -* and indicates that this Xmla.Exception signals a warning. -* -* @property TYPE_WARNING -* @static -* @final -* @type string -* @default warning -*/ -Xmla.Exception.TYPE_WARNING = "warning"; -/** -* Can appear as value for the type property of instances of the Xmla.Exception class, -* and indicates that this Xmla.Exception signals an error. -* -* @property TYPE_ERROR -* @static -* @final -* @type string -* @default error -*/ -Xmla.Exception.TYPE_ERROR = "error"; - -var _exceptionHlp = "http://code.google.com/p/xmla4js/wiki/ExceptionCodes"; - -/** -* Exception code indicating a requestType option was expected but ommitted. -* -* @property MISSING_REQUEST_TYPE_CDE -* @static -* @final -* @type {int} -* @default -1 -*/ -Xmla.Exception.MISSING_REQUEST_TYPE_CDE = -1; -Xmla.Exception.MISSING_REQUEST_TYPE_MSG = "Missing_Request_Type"; -Xmla.Exception.MISSING_REQUEST_TYPE_HLP = _exceptionHlp + - "#" + Xmla.Exception.MISSING_REQUEST_TYPE_CDE + - "_" + Xmla.Exception.MISSING_REQUEST_TYPE_MSG; -/** -* Exception code indicating a statement option was expected but ommitted. -* -* @property MISSING_STATEMENT_CDE -* @static -* @final -* @type {int} -* @default -2 -*/ -Xmla.Exception.MISSING_STATEMENT_CDE = -2; -Xmla.Exception.MISSING_STATEMENT_MSG = "Missing_Statement"; -Xmla.Exception.MISSING_STATEMENT_HLP = _exceptionHlp + - "#" + Xmla.Exception.MISSING_STATEMENT_CDE + - "_" + Xmla.Exception.MISSING_STATEMENT_MSG; - -/** -* Exception code indicating a url option was expected but ommitted. -* -* @property MISSING_URL_CDE -* @static -* @final -* @type {int} -* @default -3 -*/ -Xmla.Exception.MISSING_URL_CDE = -3; -Xmla.Exception.MISSING_URL_MSG = "Missing_URL"; -Xmla.Exception.MISSING_URL_HLP = _exceptionHlp + - "#" + Xmla.Exception.MISSING_URL_CDE + - "_" + Xmla.Exception.MISSING_URL_MSG; - -/** -* Exception code indicating a events were expected but ommitted. -* -* @property NO_EVENTS_SPECIFIED_CDE -* @static -* @final -* @type {int} -* @default -4 -*/ -Xmla.Exception.NO_EVENTS_SPECIFIED_CDE = -4; -Xmla.Exception.NO_EVENTS_SPECIFIED_MSG = "No_Events_Specified"; -Xmla.Exception.NO_EVENTS_SPECIFIED_HLP = _exceptionHlp + - "#" + Xmla.Exception.NO_EVENTS_SPECIFIED_CDE + - "_" + Xmla.Exception.NO_EVENTS_SPECIFIED_MSG; - -/** -* Exception code indicating a events were specifeid in the wrong format. -* -* @property WRONG_EVENTS_FORMAT_CDE -* @static -* @final -* @type {int} -* @default -5 -*/ -Xmla.Exception.WRONG_EVENTS_FORMAT_CDE = -5; -Xmla.Exception.WRONG_EVENTS_FORMAT_MSG = "Wrong_Events_Format"; -Xmla.Exception.WRONG_EVENTS_FORMAT_HLP = _exceptionHlp + - "#" + Xmla.Exception.NO_EVENTS_SPECIFIED_CDE + - "_" + Xmla.Exception.NO_EVENTS_SPECIFIED_MSG; - -/** -* Exception code indicating that the event name was unrecognized. -* -* @property UNKNOWN_EVENT_CDE -* @static -* @final -* @type {int} -* @default -6 -*/ -Xmla.Exception.UNKNOWN_EVENT_CDE = -6; -Xmla.Exception.UNKNOWN_EVENT_MSG = "Unknown_Event"; -Xmla.Exception.UNKNOWN_EVENT_HLP = _exceptionHlp + - "#" + Xmla.Exception.UNKNOWN_EVENT_CDE + - "_" + Xmla.Exception.UNKNOWN_EVENT_MSG; -/** -* Exception code indicating that no proper handler was passed for the events. -* -* @property INVALID_EVENT_HANDLER_CDE -* @static -* @final -* @type {int} -* @default -7 -*/ -Xmla.Exception.INVALID_EVENT_HANDLER_CDE = -7; -Xmla.Exception.INVALID_EVENT_HANDLER_MSG = "Invalid_Events_Handler"; -Xmla.Exception.INVALID_EVENT_HANDLER_HLP = _exceptionHlp + - "#" + Xmla.Exception.INVALID_EVENT_HANDLER_CDE + - "_" + Xmla.Exception.INVALID_EVENT_HANDLER_MSG; -/** -* Exception code indicating that the rrepsonse could not be parsed -* -* @property ERROR_PARSING_RESPONSE_CDE -* @static -* @final -* @type {int} -* @default -8 -*/ -Xmla.Exception.ERROR_PARSING_RESPONSE_CDE = -8; -Xmla.Exception.ERROR_PARSING_RESPONSE_MSG = "Error_Parsing_Response"; -Xmla.Exception.ERROR_PARSING_RESPONSE_HLP = _exceptionHlp + - "#" + Xmla.Exception.ERROR_PARSING_RESPONSE_CDE + - "_" + Xmla.Exception.ERROR_PARSING_RESPONSE_MSG ; -/** -* Exception code indicating the field name is not valid. -* -* @property INVALID_FIELD_CDE -* @static -* @final -* @type {int} -* @default -9 -*/ -Xmla.Exception.INVALID_FIELD_CDE = -9; -Xmla.Exception.INVALID_FIELD_MSG = "Invalid_Field"; -Xmla.Exception.INVALID_FIELD_HLP = _exceptionHlp + - "#" + Xmla.Exception.INVALID_FIELD_CDE + - "_" + Xmla.Exception.INVALID_FIELD_MSG; - -/** -* Exception code indicating a general XMLHttpRequest error. -* If this error occurs, the data object of the exception will have these members: -* -* @property HTTP_ERROR_CDE -* @static -* @final -* @type {int} -* @default -10 -*/ -Xmla.Exception.HTTP_ERROR_CDE = -10; -Xmla.Exception.HTTP_ERROR_MSG = "HTTP Error"; -Xmla.Exception.HTTP_ERROR_HLP = _exceptionHlp + - "#" + Xmla.Exception.HTTP_ERROR_CDE + - "_" + Xmla.Exception.HTTP_ERROR_MSG; - -/** -* Exception code indicating the hierarchy name is not valid. -* -* @property INVALID_HIERARCHY_CDE -* @static -* @final -* @type {int} -* @default -11 -*/ -Xmla.Exception.INVALID_HIERARCHY_CDE = -11; -Xmla.Exception.INVALID_HIERARCHY_MSG = "Invalid_Hierarchy"; -Xmla.Exception.INVALID_HIERARCHY_HLP = _exceptionHlp + - "#" + Xmla.Exception.INVALID_HIERARCHY_CDE + - "_" + Xmla.Exception.INVALID_HIERARCHY_MSG; - -/** -* Exception code indicating a problem reading a member property -* -* @property UNEXPECTED_ERROR_READING_MEMBER_CDE -* @static -* @final -* @type {int} -* @default -12 -*/ -Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_CDE = -12; -Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_MSG = "Error_Reading_Member"; -Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_HLP = _exceptionHlp + - "#" + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_CDE + - "_" + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_MSG; - -/** -* Exception code indicating the requested axis does not exist -* -* @property INVALID_AXIS -* @static -* @final -* @type {int} -* @default -13 -*/ -Xmla.Exception.INVALID_AXIS_CDE = -13; -Xmla.Exception.INVALID_AXIS_MSG = "The requested axis does not exist."; -Xmla.Exception.INVALID_AXIS_HLP = _exceptionHlp + - "#" + Xmla.Exception.INVALID_AXIS_CDE + - "_" + Xmla.Exception.INVALID_AXIS_MSG; - -/** -* Exception code indicating illegal number of axis arguments -* -* @property ILLEGAL_ARGUMENT -* @static -* @final -* @type {int} -* @default -14 -*/ -Xmla.Exception.ILLEGAL_ARGUMENT_CDE = -14; -Xmla.Exception.ILLEGAL_ARGUMENT_MSG = "Illegal arguments"; -Xmla.Exception.ILLEGAL_ARGUMENT_HLP = _exceptionHlp + - "#" + Xmla.Exception.ILLEGAL_ARGUMENT_CDE + - "_" + Xmla.Exception.ILLEGAL_ARGUMENT_MSG; - -/** -* Exception code indicating that we couldn't instantiate a xml http request object -* -* @property ERROR_INSTANTIATING_XMLHTTPREQUEST -* @static -* @final -* @type {int} -* @default -15 -*/ -Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_CDE = -15; -Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_MSG = "Error creating XML Http Request"; -Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_HLP = _exceptionHlp + - "#" + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_CDE + - "_" + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_MSG; - -Xmla.Exception._newError = function(codeName, source, data){ - return new Xmla.Exception( - Xmla.Exception.TYPE_ERROR, - Xmla.Exception[codeName + "_CDE"], - Xmla.Exception[codeName + "_MSG"], - Xmla.Exception[codeName + "_HLP"], - source, - data - ); -}; - -Xmla.Exception.prototype = { -/** -* This propery indicates what kind of exception occurred. It can have one of the following values:
-*
TYPE_WARNING
Indicates a warning
-*
TYPE_ERROR
Indicates an error
-*
-* @property type -* @type {string} -* @default {null} -*/ - type: null, -/** -* A code that can be used to identify this particular kind of exception. -* @property code -* @type {int} -* @default {null} -*/ - code: null, -/** -* A human readable message that describes the nature of the error or warning. -* @property message -* @type {string} -* @default {null} -*/ - message: null, -/** -* A name that indicates in what component (on the client or server side) this error or warning occurred. -* @property source -* @type {string} -* @default {null} -*/ - source: null, -/** -* A path or url that points to a document that contains more information about this error. -* @property helpfile -* @type {string} -* @default {null} -*/ - helpfile: null, -/** -* Additional data captured when the exception was instantiated. -* The type of information stored here is dependent upon the nature of the error. -* @property data -* @type {string} -* @default {null} -*/ - data: null, - _throw: function(){ - throw this; - }, -/** -* A reference to the built-in arguments array of the function that is throwing the exception -* This can be used to get a "stack trace" -* @property args -* @type {array} -*/ - args: null, -/** - * Returns a string representing this exception -* @method toString -* @return a string representing this exception -*/ - toString: function(){ - var string = this.type + " " + - this.code + ": " + this.message + - " (source: " + this.source + ", " + - " actor: " + this.actor + ")"; - return string; - }, -/** - * Get a stack trace. -* @method getStackTrace -* @return an array of objects describing the function on the stack -*/ - getStackTrace: function(){ - var funcstring, stack = ""; - if (this.args) { - var func = this.args.callee; - while (func){ - funcstring = String(func); - func = func.caller; + + + /** + *

+ * This class is used to indicate an runtime errors occurring in any of the methods of the xmla4js classes. + *

+ *

+ * You do not need to instantiate objects of this class yourself. + * Rather, instances of this class are created and thrown at runtime whenever an error occurs. + * The purpose is to provide a clean and clear way for applications that use xmla4js to recognize and handle Xmla4js specific runtime errors. + *

+ *

+ * To handle Xmla4js errors, you can use a try...catch block like this: + *

+
+     try {
+         ...general xmla4js work...
+     } catch (exception) {
+         if (exception instanceof Xmla.Exception) {
+             ...use exception.code, exception.message and exception.data to handle the exception.
+         } else {
+             ...handle other errors...
+         }
+     }
+    
+ * + * @class Xmla.Exception + * @constructor + */ + Xmla.Exception = function(type, code, message, helpfile, source, data, args, detail, actor){ + this.type = type; + this.code = code; + this.message = message; + this.source = source; + this.helpfile = helpfile; + this.data = data; + this.args = args; + this.detail = detail; + this.actor = actor; + return this; + }; + + /** + * Can appear as value for the type property of instances of the Xmla.Exception class, + * and indicates that this Xmla.Exception signals a warning. + * + * @property TYPE_WARNING + * @static + * @final + * @type string + * @default warning + */ + Xmla.Exception.TYPE_WARNING = "warning"; + /** + * Can appear as value for the type property of instances of the Xmla.Exception class, + * and indicates that this Xmla.Exception signals an error. + * + * @property TYPE_ERROR + * @static + * @final + * @type string + * @default error + */ + Xmla.Exception.TYPE_ERROR = "error"; + + var _exceptionHlp = "http://code.google.com/p/xmla4js/wiki/ExceptionCodes"; + + /** + * Exception code indicating a requestType option was expected but ommitted. + * + * @property MISSING_REQUEST_TYPE_CDE + * @static + * @final + * @type {int} + * @default -1 + */ + Xmla.Exception.MISSING_REQUEST_TYPE_CDE = -1; + Xmla.Exception.MISSING_REQUEST_TYPE_MSG = "Missing_Request_Type"; + Xmla.Exception.MISSING_REQUEST_TYPE_HLP = _exceptionHlp + + "#" + Xmla.Exception.MISSING_REQUEST_TYPE_CDE + + "_" + Xmla.Exception.MISSING_REQUEST_TYPE_MSG; + /** + * Exception code indicating a statement option was expected but ommitted. + * + * @property MISSING_STATEMENT_CDE + * @static + * @final + * @type {int} + * @default -2 + */ + Xmla.Exception.MISSING_STATEMENT_CDE = -2; + Xmla.Exception.MISSING_STATEMENT_MSG = "Missing_Statement"; + Xmla.Exception.MISSING_STATEMENT_HLP = _exceptionHlp + + "#" + Xmla.Exception.MISSING_STATEMENT_CDE + + "_" + Xmla.Exception.MISSING_STATEMENT_MSG; + + /** + * Exception code indicating a url option was expected but ommitted. + * + * @property MISSING_URL_CDE + * @static + * @final + * @type {int} + * @default -3 + */ + Xmla.Exception.MISSING_URL_CDE = -3; + Xmla.Exception.MISSING_URL_MSG = "Missing_URL"; + Xmla.Exception.MISSING_URL_HLP = _exceptionHlp + + "#" + Xmla.Exception.MISSING_URL_CDE + + "_" + Xmla.Exception.MISSING_URL_MSG; + + /** + * Exception code indicating a events were expected but ommitted. + * + * @property NO_EVENTS_SPECIFIED_CDE + * @static + * @final + * @type {int} + * @default -4 + */ + Xmla.Exception.NO_EVENTS_SPECIFIED_CDE = -4; + Xmla.Exception.NO_EVENTS_SPECIFIED_MSG = "No_Events_Specified"; + Xmla.Exception.NO_EVENTS_SPECIFIED_HLP = _exceptionHlp + + "#" + Xmla.Exception.NO_EVENTS_SPECIFIED_CDE + + "_" + Xmla.Exception.NO_EVENTS_SPECIFIED_MSG; + + /** + * Exception code indicating a events were specifeid in the wrong format. + * + * @property WRONG_EVENTS_FORMAT_CDE + * @static + * @final + * @type {int} + * @default -5 + */ + Xmla.Exception.WRONG_EVENTS_FORMAT_CDE = -5; + Xmla.Exception.WRONG_EVENTS_FORMAT_MSG = "Wrong_Events_Format"; + Xmla.Exception.WRONG_EVENTS_FORMAT_HLP = _exceptionHlp + + "#" + Xmla.Exception.NO_EVENTS_SPECIFIED_CDE + + "_" + Xmla.Exception.NO_EVENTS_SPECIFIED_MSG; + + /** + * Exception code indicating that the event name was unrecognized. + * + * @property UNKNOWN_EVENT_CDE + * @static + * @final + * @type {int} + * @default -6 + */ + Xmla.Exception.UNKNOWN_EVENT_CDE = -6; + Xmla.Exception.UNKNOWN_EVENT_MSG = "Unknown_Event"; + Xmla.Exception.UNKNOWN_EVENT_HLP = _exceptionHlp + + "#" + Xmla.Exception.UNKNOWN_EVENT_CDE + + "_" + Xmla.Exception.UNKNOWN_EVENT_MSG; + /** + * Exception code indicating that no proper handler was passed for the events. + * + * @property INVALID_EVENT_HANDLER_CDE + * @static + * @final + * @type {int} + * @default -7 + */ + Xmla.Exception.INVALID_EVENT_HANDLER_CDE = -7; + Xmla.Exception.INVALID_EVENT_HANDLER_MSG = "Invalid_Events_Handler"; + Xmla.Exception.INVALID_EVENT_HANDLER_HLP = _exceptionHlp + + "#" + Xmla.Exception.INVALID_EVENT_HANDLER_CDE + + "_" + Xmla.Exception.INVALID_EVENT_HANDLER_MSG; + /** + * Exception code indicating that the rrepsonse could not be parsed + * + * @property ERROR_PARSING_RESPONSE_CDE + * @static + * @final + * @type {int} + * @default -8 + */ + Xmla.Exception.ERROR_PARSING_RESPONSE_CDE = -8; + Xmla.Exception.ERROR_PARSING_RESPONSE_MSG = "Error_Parsing_Response"; + Xmla.Exception.ERROR_PARSING_RESPONSE_HLP = _exceptionHlp + + "#" + Xmla.Exception.ERROR_PARSING_RESPONSE_CDE + + "_" + Xmla.Exception.ERROR_PARSING_RESPONSE_MSG ; + /** + * Exception code indicating the field name is not valid. + * + * @property INVALID_FIELD_CDE + * @static + * @final + * @type {int} + * @default -9 + */ + Xmla.Exception.INVALID_FIELD_CDE = -9; + Xmla.Exception.INVALID_FIELD_MSG = "Invalid_Field"; + Xmla.Exception.INVALID_FIELD_HLP = _exceptionHlp + + "#" + Xmla.Exception.INVALID_FIELD_CDE + + "_" + Xmla.Exception.INVALID_FIELD_MSG; + + /** + * Exception code indicating a general XMLHttpRequest error. + * If this error occurs, the data object of the exception will have these members: + * + * @property HTTP_ERROR_CDE + * @static + * @final + * @type {int} + * @default -10 + */ + Xmla.Exception.HTTP_ERROR_CDE = -10; + Xmla.Exception.HTTP_ERROR_MSG = "HTTP Error"; + Xmla.Exception.HTTP_ERROR_HLP = _exceptionHlp + + "#" + Xmla.Exception.HTTP_ERROR_CDE + + "_" + Xmla.Exception.HTTP_ERROR_MSG; + + /** + * Exception code indicating the hierarchy name is not valid. + * + * @property INVALID_HIERARCHY_CDE + * @static + * @final + * @type {int} + * @default -11 + */ + Xmla.Exception.INVALID_HIERARCHY_CDE = -11; + Xmla.Exception.INVALID_HIERARCHY_MSG = "Invalid_Hierarchy"; + Xmla.Exception.INVALID_HIERARCHY_HLP = _exceptionHlp + + "#" + Xmla.Exception.INVALID_HIERARCHY_CDE + + "_" + Xmla.Exception.INVALID_HIERARCHY_MSG; + + /** + * Exception code indicating a problem reading a member property + * + * @property UNEXPECTED_ERROR_READING_MEMBER_CDE + * @static + * @final + * @type {int} + * @default -12 + */ + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_CDE = -12; + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_MSG = "Error_Reading_Member"; + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_HLP = _exceptionHlp + + "#" + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_CDE + + "_" + Xmla.Exception.UNEXPECTED_ERROR_READING_MEMBER_MSG; + + /** + * Exception code indicating the requested axis does not exist + * + * @property INVALID_AXIS + * @static + * @final + * @type {int} + * @default -13 + */ + Xmla.Exception.INVALID_AXIS_CDE = -13; + Xmla.Exception.INVALID_AXIS_MSG = "The requested axis does not exist."; + Xmla.Exception.INVALID_AXIS_HLP = _exceptionHlp + + "#" + Xmla.Exception.INVALID_AXIS_CDE + + "_" + Xmla.Exception.INVALID_AXIS_MSG; + + /** + * Exception code indicating illegal number of axis arguments + * + * @property ILLEGAL_ARGUMENT + * @static + * @final + * @type {int} + * @default -14 + */ + Xmla.Exception.ILLEGAL_ARGUMENT_CDE = -14; + Xmla.Exception.ILLEGAL_ARGUMENT_MSG = "Illegal arguments"; + Xmla.Exception.ILLEGAL_ARGUMENT_HLP = _exceptionHlp + + "#" + Xmla.Exception.ILLEGAL_ARGUMENT_CDE + + "_" + Xmla.Exception.ILLEGAL_ARGUMENT_MSG; + + /** + * Exception code indicating that we couldn't instantiate a xml http request object + * + * @property ERROR_INSTANTIATING_XMLHTTPREQUEST + * @static + * @final + * @type {int} + * @default -15 + */ + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_CDE = -15; + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_MSG = "Error creating XML Http Request"; + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_HLP = _exceptionHlp + + "#" + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_CDE + + "_" + Xmla.Exception.ERROR_INSTANTIATING_XMLHTTPREQUEST_MSG; + + Xmla.Exception._newError = function(codeName, source, data){ + return new Xmla.Exception( + Xmla.Exception.TYPE_ERROR, + Xmla.Exception[codeName + "_CDE"], + Xmla.Exception[codeName + "_MSG"], + Xmla.Exception[codeName + "_HLP"], + source, + data + ); + }; + + Xmla.Exception.prototype = { + /** + * This propery indicates what kind of exception occurred. It can have one of the following values:
+ *
TYPE_WARNING
Indicates a warning
+ *
TYPE_ERROR
Indicates an error
+ *
+ * @property type + * @type {string} + * @default {null} + */ + type: null, + /** + * A code that can be used to identify this particular kind of exception. + * @property code + * @type {int} + * @default {null} + */ + code: null, + /** + * A human readable message that describes the nature of the error or warning. + * @property message + * @type {string} + * @default {null} + */ + message: null, + /** + * A name that indicates in what component (on the client or server side) this error or warning occurred. + * @property source + * @type {string} + * @default {null} + */ + source: null, + /** + * A path or url that points to a document that contains more information about this error. + * @property helpfile + * @type {string} + * @default {null} + */ + helpfile: null, + /** + * Additional data captured when the exception was instantiated. + * The type of information stored here is dependent upon the nature of the error. + * @property data + * @type {string} + * @default {null} + */ + data: null, + _throw: function(){ + throw this; + }, + /** + * A reference to the built-in arguments array of the function that is throwing the exception + * This can be used to get a "stack trace" + * @property args + * @type {array} + */ + args: null, + /** + * Returns a string representing this exception + * @method toString + * @return a string representing this exception + */ + toString: function(){ + var string = this.type + " " + + this.code + ": " + this.message + + " (source: " + this.source + ", " + + " actor: " + this.actor + ")"; + return string; + }, + /** + * Get a stack trace. + * @method getStackTrace + * @return an array of objects describing the function on the stack + */ + getStackTrace: function(){ + var funcstring, stack = ""; + if (this.args) { + var func = this.args.callee; + while (func){ + funcstring = String(func); + func = func.caller; + } } + return stack; } - return stack; + }; + + /* + * Register Xmla. + * In an amd (https://github.com/amdjs/amdjs-api/wiki/AMD) environment, use the define function + * Otherwise, add it to the global window variable. + * For server side environemnts that do not have a proper window object, + * simply create a global variable called window and assign an object to it that you want to function as the Xmla container. + */ + if (typeof(define)==="function" && define.amd) { + define(function (){ + return Xmla; + }); } -}; - -/* -* Register Xmla. -* In an amd (https://github.com/amdjs/amdjs-api/wiki/AMD) environment, use the define function -* Otherwise, add it to the global window variable. -* For server side environemnts that do not have a proper window object, -* simply create a global variable called window and assign an object to it that you want to function as the Xmla container. -*/ -if (typeof(define)==="function" && define.amd) { - define(function (){ - return Xmla; - }); -} -else { - window.Xmla = Xmla; -} -return Xmla; -})(typeof exports === "undefined" ? window : exports); + else { + window.Xmla = Xmla; + } + return Xmla; + })(typeof exports === "undefined" ? window : exports); + \ No newline at end of file