📄 common.js
字号:
}catch(execError){ error = true; exp = execError.message||execError; } // was there an error during SQL execution? if(exp != null){ if(dojox.sql._autoClose){ try{ dojox.sql.close(); }catch(e){} } callback(null, true, exp.toString()); return; } // normalize SQL results into a JavaScript object // we can work with resultSet = dojox.sql._normalizeResults(resultSet); if(dojox.sql._autoClose){ dojox.sql.close(); } // are any decryptions necessary on the result set? if(dojox.sql._needsDecrypt(sql)){ // determine which of the result set columns needs decryption var needsDecrypt = self._determineDecryptedColumns(sql); // now decrypt columns asynchronously // decrypt columns that need it self._decrypt(resultSet, needsDecrypt, password, function(finalResultSet){ callback(finalResultSet, false, null); }); }else{ callback(resultSet, false, null); } }); }, _execDecryptSQL: function(sql, password, args, callback){ // strip the ENCRYPT/DECRYPT keywords from the SQL var strippedSQL = this._stripCryptoSQL(sql); // determine which columns needs decryption; this either // returns the value *, which means all result set columns will // be decrypted, or it will return the column names that need // decryption set on a hashtable so we can quickly test a given // column name; the key is the column name that needs // decryption and the value is 'true' (i.e. needsDecrypt["someColumn"] // would return 'true' if it needs decryption, and would be 'undefined' // or false otherwise) var needsDecrypt = this._determineDecryptedColumns(sql); // execute the SQL var error = false; var resultSet = []; var exp = null; try{ resultSet = dojox.sql.db.execute(strippedSQL, args); }catch(execError){ error = true; exp = execError.message||execError; } // was there an error during SQL execution? if(exp != null){ if(dojox.sql._autoClose){ try{ dojox.sql.close(); }catch(e){} } callback(resultSet, true, exp.toString()); return; } // normalize SQL results into a JavaScript object // we can work with resultSet = dojox.sql._normalizeResults(resultSet); if(dojox.sql._autoClose){ dojox.sql.close(); } // decrypt columns that need it this._decrypt(resultSet, needsDecrypt, password, function(finalResultSet){ callback(finalResultSet, false, null); }); }, _encrypt: function(sql, password, args, encryptColumns, callback){ //console.debug("_encrypt, sql="+sql+", password="+password+", encryptColumns="+encryptColumns+", args="+args); this._totalCrypto = 0; this._finishedCrypto = 0; this._finishedSpawningCrypto = false; this._finalArgs = args; for(var i = 0; i < args.length; i++){ if(encryptColumns[i]){ // we have an encrypt() keyword -- get just the value inside // the encrypt() parantheses -- for now this must be a ? var sqlParam = args[i]; var paramIndex = i; // update the total number of encryptions we know must be done asynchronously this._totalCrypto++; // FIXME: This currently uses DES as a proof-of-concept since the // DES code used is quite fast and was easy to work with. Modify dojox.sql // to be able to specify a different encryption provider through a // a SQL-like syntax, such as dojox.sql("SET ENCRYPTION BLOWFISH"), // and modify the dojox.crypto.Blowfish code to be able to work using // a Google Gears Worker Pool // do the actual encryption now, asychronously on a Gears worker thread dojox._sql._crypto.encrypt(sqlParam, password, dojo.hitch(this, function(results){ // set the new encrypted value this._finalArgs[paramIndex] = results; this._finishedCrypto++; // are we done with all encryption? if(this._finishedCrypto >= this._totalCrypto && this._finishedSpawningCrypto){ callback(this._finalArgs); } })); } } this._finishedSpawningCrypto = true; }, _decrypt: function(resultSet, needsDecrypt, password, callback){ //console.debug("decrypt, resultSet="+resultSet+", needsDecrypt="+needsDecrypt+", password="+password); this._totalCrypto = 0; this._finishedCrypto = 0; this._finishedSpawningCrypto = false; this._finalResultSet = resultSet; for(var i = 0; i < resultSet.length; i++){ var row = resultSet[i]; // go through each of the column names in row, // seeing if they need decryption for(var columnName in row){ if(needsDecrypt == "*" || needsDecrypt[columnName]){ this._totalCrypto++; var columnValue = row[columnName]; // forming a closure here can cause issues, with values not cleanly // saved on Firefox/Mac OS X for some of the values above that // are needed in the callback below; call a subroutine that will form // a closure inside of itself instead this._decryptSingleColumn(columnName, columnValue, password, i, function(finalResultSet){ callback(finalResultSet); }); } } } this._finishedSpawningCrypto = true; }, _stripCryptoSQL: function(sql){ // replace all DECRYPT(*) occurrences with a * sql = sql.replace(/DECRYPT\(\*\)/ig, "*"); // match any ENCRYPT(?, ?, ?, etc) occurrences, // then replace with just the question marks in the // middle var matches = sql.match(/ENCRYPT\([^\)]*\)/ig); if(matches != null){ for(var i = 0; i < matches.length; i++){ var encryptStatement = matches[i]; var encryptValue = encryptStatement.match(/ENCRYPT\(([^\)]*)\)/i)[1]; sql = sql.replace(encryptStatement, encryptValue); } } // match any DECRYPT(COL1, COL2, etc) occurrences, // then replace with just the column names // in the middle matches = sql.match(/DECRYPT\([^\)]*\)/ig); if(matches != null){ for(var i = 0; i < matches.length; i++){ var decryptStatement = matches[i]; var decryptValue = decryptStatement.match(/DECRYPT\(([^\)]*)\)/i)[1]; sql = sql.replace(decryptStatement, decryptValue); } } return sql; }, _flagEncryptedArgs: function(sql, args){ // capture literal strings that have question marks in them, // and also capture question marks that stand alone var tester = new RegExp(/([\"][^\"]*\?[^\"]*[\"])|([\'][^\']*\?[^\']*[\'])|(\?)/ig); var matches; var currentParam = 0; var results = []; while((matches = tester.exec(sql)) != null){ var currentMatch = RegExp.lastMatch+""; // are we a literal string? then ignore it if(/^[\"\']/.test(currentMatch)){ continue; } // do we have an encrypt keyword to our left? var needsEncrypt = false; if(/ENCRYPT\([^\)]*$/i.test(RegExp.leftContext)){ needsEncrypt = true; } // set the encrypted flag results[currentParam] = needsEncrypt; currentParam++; } return results; }, _determineDecryptedColumns: function(sql){ var results = {}; if(/DECRYPT\(\*\)/i.test(sql)){ results = "*"; }else{ var tester = /DECRYPT\((?:\s*\w*\s*\,?)*\)/ig; var matches; while(matches = tester.exec(sql)){ var lastMatch = new String(RegExp.lastMatch); var columnNames = lastMatch.replace(/DECRYPT\(/i, ""); columnNames = columnNames.replace(/\)/, ""); columnNames = columnNames.split(/\s*,\s*/); dojo.forEach(columnNames, function(column){ if(/\s*\w* AS (\w*)/i.test(column)){ column = column.match(/\s*\w* AS (\w*)/i)[1]; } results[column] = true; }); } } return results; }, _decryptSingleColumn: function(columnName, columnValue, password, currentRowIndex, callback){ //console.debug("decryptSingleColumn, columnName="+columnName+", columnValue="+columnValue+", currentRowIndex="+currentRowIndex) dojox._sql._crypto.decrypt(columnValue, password, dojo.hitch(this, function(results){ // set the new decrypted value this._finalResultSet[currentRowIndex][columnName] = results; this._finishedCrypto++; // are we done with all encryption? if(this._finishedCrypto >= this._totalCrypto && this._finishedSpawningCrypto){ //console.debug("done with all decrypts"); callback(this._finalResultSet); } })); }});}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -