diff options
Diffstat (limited to 'includes/js/dojox/data/CsvStore.js')
-rw-r--r-- | includes/js/dojox/data/CsvStore.js | 561 |
1 files changed, 0 insertions, 561 deletions
diff --git a/includes/js/dojox/data/CsvStore.js b/includes/js/dojox/data/CsvStore.js deleted file mode 100644 index 87f7466..0000000 --- a/includes/js/dojox/data/CsvStore.js +++ /dev/null @@ -1,561 +0,0 @@ -if(!dojo._hasResource["dojox.data.CsvStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. -dojo._hasResource["dojox.data.CsvStore"] = true; -dojo.provide("dojox.data.CsvStore"); - -dojo.require("dojo.data.util.filter"); -dojo.require("dojo.data.util.simpleFetch"); - -dojo.declare("dojox.data.CsvStore", null, { - // summary: - // The CsvStore implements the dojo.data.api.Read API and reads - // data from files in CSV (Comma Separated Values) format. - // All values are simple string values. References to other items - // are not supported as attribute values in this datastore. - // - // Example data file: - // name, color, age, tagline - // Kermit, green, 12, "Hi, I'm Kermit the Frog." - // Fozzie Bear, orange, 10, "Wakka Wakka Wakka!" - // Miss Piggy, pink, 11, "Kermie!" - // - // Note that values containing a comma must be enclosed with quotes ("") - // Also note that values containing quotes must be escaped with two consecutive quotes (""quoted"") - - /* examples: - * var csvStore = new dojox.data.CsvStore({url:"movies.csv"); - * var csvStore = new dojox.data.CsvStore({url:"http://example.com/movies.csv"); - */ - - constructor: function(/* Object */ keywordParameters){ - // summary: initializer - // keywordParameters: {url: String} - // keywordParameters: {data: String} - // keywordParameters: {label: String} The column label for the column to use for the label returned by getLabel. - - this._attributes = []; // e.g. ["Title", "Year", "Producer"] - this._attributeIndexes = {}; // e.g. {Title: 0, Year: 1, Producer: 2} - this._dataArray = []; // e.g. [[<Item0>],[<Item1>],[<Item2>]] - this._arrayOfAllItems = []; // e.g. [{_csvId:0,_csvStore:store},...] - this._loadFinished = false; - if(keywordParameters.url){ - this.url = keywordParameters.url; - } - this._csvData = keywordParameters.data; - if(keywordParameters.label){ - this.label = keywordParameters.label; - }else if(this.label === ""){ - this.label = undefined; - } - this._storeProp = "_csvStore"; // Property name for the store reference on every item. - this._idProp = "_csvId"; // Property name for the Item Id on every item. - this._features = { - 'dojo.data.api.Read': true, - 'dojo.data.api.Identity': true - }; - this._loadInProgress = false; //Got to track the initial load to prevent duelling loads of the dataset. - this._queuedFetches = []; - }, - - url: "", //Declarative hook for setting Csv source url. - - label: "", //Declarative hook for setting the label attribute. - - _assertIsItem: function(/* item */ item){ - // summary: - // This function tests whether the item passed in is indeed an item in the store. - // item: - // The item to test for being contained by the store. - if(!this.isItem(item)){ - throw new Error("dojox.data.CsvStore: a function was passed an item argument that was not an item"); - } - }, - - _assertIsAttribute: function(/* item || String */ attribute){ - // summary: - // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store. - // attribute: - // The attribute to test for being contained by the store. - if(!dojo.isString(attribute)){ - throw new Error("dojox.data.CsvStore: a function was passed an attribute argument that was not an attribute object nor an attribute name string"); - } - }, - -/*************************************** - dojo.data.api.Read API -***************************************/ - getValue: function( /* item */ item, - /* attribute || attribute-name-string */ attribute, - /* value? */ defaultValue){ - // summary: - // See dojo.data.api.Read.getValue() - // Note that for the CsvStore, an empty string value is the same as no value, - // so the defaultValue would be returned instead of an empty string. - this._assertIsItem(item); - this._assertIsAttribute(attribute); - var itemValue = defaultValue; - if(this.hasAttribute(item, attribute)){ - var itemData = this._dataArray[this.getIdentity(item)]; - itemValue = itemData[this._attributeIndexes[attribute]]; - } - return itemValue; //String - }, - - getValues: function(/* item */ item, - /* attribute || attribute-name-string */ attribute){ - // summary: - // See dojo.data.api.Read.getValues() - // CSV syntax does not support multi-valued attributes, so this is just a - // wrapper function for getValue(). - var value = this.getValue(item, attribute); - return (value ? [value] : []); //Array - }, - - getAttributes: function(/* item */ item){ - // summary: - // See dojo.data.api.Read.getAttributes() - this._assertIsItem(item); - var attributes = []; - var itemData = this._dataArray[this.getIdentity(item)]; - for(var i=0; i<itemData.length; i++){ - // Check for empty string values. CsvStore treats empty strings as no value. - if(itemData[i] != ""){ - attributes.push(this._attributes[i]); - } - } - return attributes; //Array - }, - - hasAttribute: function( /* item */ item, - /* attribute || attribute-name-string */ attribute){ - // summary: - // See dojo.data.api.Read.hasAttribute() - // The hasAttribute test is true if attribute has an index number within the item's array length - // AND if the item has a value for that attribute. Note that for the CsvStore, an - // empty string value is the same as no value. - this._assertIsItem(item); - this._assertIsAttribute(attribute); - var attributeIndex = this._attributeIndexes[attribute]; - var itemData = this._dataArray[this.getIdentity(item)]; - return (typeof attributeIndex != "undefined" && attributeIndex < itemData.length && itemData[attributeIndex] != ""); //Boolean - }, - - containsValue: function(/* item */ item, - /* attribute || attribute-name-string */ attribute, - /* anything */ value){ - // summary: - // See dojo.data.api.Read.containsValue() - var regexp = undefined; - if(typeof value === "string"){ - regexp = dojo.data.util.filter.patternToRegExp(value, false); - } - return this._containsValue(item, attribute, value, regexp); //boolean. - }, - - _containsValue: function( /* item */ item, - /* attribute || attribute-name-string */ attribute, - /* anything */ value, - /* RegExp?*/ regexp){ - // summary: - // Internal function for looking at the values contained by the item. - // description: - // Internal function for looking at the values contained by the item. This - // function allows for denoting if the comparison should be case sensitive for - // strings or not (for handling filtering cases where string case should not matter) - // - // item: - // The data item to examine for attribute values. - // attribute: - // The attribute to inspect. - // value: - // The value to match. - // regexp: - // Optional regular expression generated off value if value was of string type to handle wildcarding. - // If present and attribute values are string, then it can be used for comparison instead of 'value' - var values = this.getValues(item, attribute); - for(var i = 0; i < values.length; ++i){ - var possibleValue = values[i]; - if(typeof possibleValue === "string" && regexp){ - return (possibleValue.match(regexp) !== null); - }else{ - //Non-string matching. - if(value === possibleValue){ - return true; // Boolean - } - } - } - return false; // Boolean - }, - - isItem: function(/* anything */ something){ - // summary: - // See dojo.data.api.Read.isItem() - if(something && something[this._storeProp] === this){ - var identity = something[this._idProp]; - if(identity >= 0 && identity < this._dataArray.length){ - return true; //Boolean - } - } - return false; //Boolean - }, - - isItemLoaded: function(/* anything */ something){ - // summary: - // See dojo.data.api.Read.isItemLoaded() - // The CsvStore always loads all items, so if it's an item, then it's loaded. - return this.isItem(something); //Boolean - }, - - loadItem: function(/* item */ item){ - // summary: - // See dojo.data.api.Read.loadItem() - // description: - // The CsvStore always loads all items, so if it's an item, then it's loaded. - // From the dojo.data.api.Read.loadItem docs: - // If a call to isItemLoaded() returns true before loadItem() is even called, - // then loadItem() need not do any work at all and will not even invoke - // the callback handlers. - }, - - getFeatures: function(){ - // summary: - // See dojo.data.api.Read.getFeatures() - return this._features; //Object - }, - - getLabel: function(/* item */ item){ - // summary: - // See dojo.data.api.Read.getLabel() - if(this.label && this.isItem(item)){ - return this.getValue(item,this.label); //String - } - return undefined; //undefined - }, - - getLabelAttributes: function(/* item */ item){ - // summary: - // See dojo.data.api.Read.getLabelAttributes() - if(this.label){ - return [this.label]; //array - } - return null; //null - }, - - - // The dojo.data.api.Read.fetch() function is implemented as - // a mixin from dojo.data.util.simpleFetch. - // That mixin requires us to define _fetchItems(). - _fetchItems: function( /* Object */ keywordArgs, - /* Function */ findCallback, - /* Function */ errorCallback){ - // summary: - // See dojo.data.util.simpleFetch.fetch() - - var self = this; - - var filter = function(requestArgs, arrayOfAllItems){ - var items = null; - if(requestArgs.query){ - items = []; - var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; - - //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the - //same value for each item examined. Much more efficient. - var regexpList = {}; - for(var key in requestArgs.query){ - var value = requestArgs.query[key]; - if(typeof value === "string"){ - regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase); - } - } - - for(var i = 0; i < arrayOfAllItems.length; ++i){ - var match = true; - var candidateItem = arrayOfAllItems[i]; - for(var key in requestArgs.query){ - var value = requestArgs.query[key]; - if(!self._containsValue(candidateItem, key, value, regexpList[key])){ - match = false; - } - } - if(match){ - items.push(candidateItem); - } - } - }else{ - // We want a copy to pass back in case the parent wishes to sort the array. We shouldn't allow resort - // of the internal list so that multiple callers can get lists and sort without affecting each other. - if(arrayOfAllItems.length> 0){ - items = arrayOfAllItems.slice(0,arrayOfAllItems.length); - } - } - findCallback(items, requestArgs); - }; - - if(this._loadFinished){ - filter(keywordArgs, this._arrayOfAllItems); - }else{ - if(this.url !== ""){ - //If fetches come in before the loading has finished, but while - //a load is in progress, we have to defer the fetching to be - //invoked in the callback. - if(this._loadInProgress){ - this._queuedFetches.push({args: keywordArgs, filter: filter}); - }else{ - this._loadInProgress = true; - var getArgs = { - url: self.url, - handleAs: "text" - }; - var getHandler = dojo.xhrGet(getArgs); - getHandler.addCallback(function(data){ - self._processData(data); - filter(keywordArgs, self._arrayOfAllItems); - self._handleQueuedFetches(); - }); - getHandler.addErrback(function(error){ - self._loadInProgress = false; - if(errorCallback){ - errorCallback(error, keywordArgs); - }else{ - throw error; - } - }); - } - }else if(this._csvData){ - this._processData(this._csvData); - this._csvData = null; - filter(keywordArgs, this._arrayOfAllItems); - }else{ - var error = new Error("dojox.data.CsvStore: No CSV source data was provided as either URL or String data input."); - if(errorCallback){ - errorCallback(error, keywordArgs); - }else{ - throw error; - } - } - } - }, - - close: function(/*dojo.data.api.Request || keywordArgs || null */ request){ - // summary: - // See dojo.data.api.Read.close() - }, - - - // ------------------------------------------------------------------- - // Private methods - _getArrayOfArraysFromCsvFileContents: function(/* string */ csvFileContents){ - /* summary: - * Parses a string of CSV records into a nested array structure. - * description: - * Given a string containing CSV records, this method parses - * the string and returns a data structure containing the parsed - * content. The data structure we return is an array of length - * R, where R is the number of rows (lines) in the CSV data. The - * return array contains one sub-array for each CSV line, and each - * sub-array contains C string values, where C is the number of - * columns in the CSV data. - */ - - /* example: - * For example, given this CSV string as input: - * "Title, Year, Producer \n Alien, 1979, Ridley Scott \n Blade Runner, 1982, Ridley Scott" - * this._dataArray will be set to: - * [["Alien", "1979", "Ridley Scott"], - * ["Blade Runner", "1982", "Ridley Scott"]] - * And this._attributes will be set to: - * ["Title", "Year", "Producer"] - * And this._attributeIndexes will be set to: - * { "Title":0, "Year":1, "Producer":2 } - */ - if(dojo.isString(csvFileContents)){ - var lineEndingCharacters = new RegExp("\r\n|\n|\r"); - var leadingWhiteSpaceCharacters = new RegExp("^\\s+",'g'); - var trailingWhiteSpaceCharacters = new RegExp("\\s+$",'g'); - var doubleQuotes = new RegExp('""','g'); - var arrayOfOutputRecords = []; - - var arrayOfInputLines = csvFileContents.split(lineEndingCharacters); - for(var i = 0; i < arrayOfInputLines.length; ++i){ - var singleLine = arrayOfInputLines[i]; - if(singleLine.length > 0){ - var listOfFields = singleLine.split(','); - var j = 0; - while(j < listOfFields.length){ - var space_field_space = listOfFields[j]; - var field_space = space_field_space.replace(leadingWhiteSpaceCharacters, ''); // trim leading whitespace - var field = field_space.replace(trailingWhiteSpaceCharacters, ''); // trim trailing whitespace - var firstChar = field.charAt(0); - var lastChar = field.charAt(field.length - 1); - var secondToLastChar = field.charAt(field.length - 2); - var thirdToLastChar = field.charAt(field.length - 3); - if(field.length === 2 && field == "\"\""){ - listOfFields[j] = ""; //Special case empty string field. - }else if((firstChar == '"') && - ((lastChar != '"') || - ((lastChar == '"') && (secondToLastChar == '"') && (thirdToLastChar != '"')))){ - if(j+1 === listOfFields.length){ - // alert("The last field in record " + i + " is corrupted:\n" + field); - return null; //null - } - var nextField = listOfFields[j+1]; - listOfFields[j] = field_space + ',' + nextField; - listOfFields.splice(j+1, 1); // delete element [j+1] from the list - }else{ - if((firstChar == '"') && (lastChar == '"')){ - field = field.slice(1, (field.length - 1)); // trim the " characters off the ends - field = field.replace(doubleQuotes, '"'); // replace "" with " - } - listOfFields[j] = field; - j += 1; - } - } - arrayOfOutputRecords.push(listOfFields); - } - } - - // The first item of the array must be the header row with attribute names. - this._attributes = arrayOfOutputRecords.shift(); - for(var i=0; i<this._attributes.length; i++){ - // Store the index of each attribute - this._attributeIndexes[this._attributes[i]] = i; - } - this._dataArray = arrayOfOutputRecords; //Array - } - }, - - _processData: function(/* String */ data){ - this._getArrayOfArraysFromCsvFileContents(data); - this._arrayOfAllItems = []; - for(var i=0; i<this._dataArray.length; i++){ - this._arrayOfAllItems.push(this._createItemFromIdentity(i)); - } - this._loadFinished = true; - this._loadInProgress = false; - }, - - _createItemFromIdentity: function(/* String */ identity){ - var item = {}; - item[this._storeProp] = this; - item[this._idProp] = identity; - return item; //Object - }, - - -/*************************************** - dojo.data.api.Identity API -***************************************/ - getIdentity: function(/* item */ item){ - // summary: - // See dojo.data.api.Identity.getIdentity() - if(this.isItem(item)){ - return item[this._idProp]; //String - } - return null; //null - }, - - fetchItemByIdentity: function(/* Object */ keywordArgs){ - // summary: - // See dojo.data.api.Identity.fetchItemByIdentity() - - //Hasn't loaded yet, we have to trigger the load. - - - if(!this._loadFinished){ - var self = this; - if(this.url !== ""){ - //If fetches come in before the loading has finished, but while - //a load is in progress, we have to defer the fetching to be - //invoked in the callback. - if(this._loadInProgress){ - this._queuedFetches.push({args: keywordArgs}); - }else{ - this._loadInProgress = true; - var getArgs = { - url: self.url, - handleAs: "text" - }; - var getHandler = dojo.xhrGet(getArgs); - getHandler.addCallback(function(data){ - var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; - try{ - self._processData(data); - var item = self._createItemFromIdentity(keywordArgs.identity); - if(!self.isItem(item)){ - item = null; - } - if(keywordArgs.onItem){ - keywordArgs.onItem.call(scope, item); - } - self._handleQueuedFetches(); - }catch(error){ - if(keywordArgs.onError){ - keywordArgs.onError.call(scope, error); - } - } - }); - getHandler.addErrback(function(error){ - this._loadInProgress = false; - if(keywordArgs.onError){ - var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; - keywordArgs.onError.call(scope, error); - } - }); - } - }else if(this._csvData){ - self._processData(self._csvData); - self._csvData = null; - var item = self._createItemFromIdentity(keywordArgs.identity); - if(!self.isItem(item)){ - item = null; - } - if(keywordArgs.onItem){ - var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; - keywordArgs.onItem.call(scope, item); - } - } - }else{ - //Already loaded. We can just look it up and call back. - var item = this._createItemFromIdentity(keywordArgs.identity); - if(!this.isItem(item)){ - item = null; - } - if(keywordArgs.onItem){ - var scope = keywordArgs.scope?keywordArgs.scope:dojo.global; - keywordArgs.onItem.call(scope, item); - } - } - }, - - getIdentityAttributes: function(/* item */ item){ - // summary: - // See dojo.data.api.Identity.getIdentifierAttributes() - - //Identity isn't a public attribute in the item, it's the row position index. - //So, return null. - return null; - }, - - _handleQueuedFetches: function(){ - // summary: - // Internal function to execute delayed request in the store. - //Execute any deferred fetches now. - if (this._queuedFetches.length > 0) { - for(var i = 0; i < this._queuedFetches.length; i++){ - var fData = this._queuedFetches[i]; - var delayedFilter = fData.filter; - var delayedQuery = fData.args; - if(delayedFilter){ - delayedFilter(delayedQuery, this._arrayOfAllItems); - }else{ - this.fetchItemByIdentity(fData.args); - } - } - this._queuedFetches = []; - } - } -}); -//Mix in the simple fetch implementation to this class. -dojo.extend(dojox.data.CsvStore,dojo.data.util.simpleFetch); - -} |