1 // 2 // The Antville Project 3 // http://code.google.com/p/antville 4 // 5 // Copyright 2001-2007 by The Antville People 6 // 7 // Licensed under the Apache License, Version 2.0 (the ``License''); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an ``AS IS'' BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 // $Revision$ 20 // $LastChangedBy$ 21 // $LastChangedDate$ 22 // $URL$ 23 // 24 25 /** 26 * @fileOverview Defines the Sql prototype, a utility for relational queries 27 */ 28 29 /** 30 * @constructor 31 */ 32 var Sql = function() { 33 var db = getDBConnection("antville"); 34 var query; 35 36 var log = new function() { 37 var fname = getProperty("sqlLog", "helma." + app.getName() + ".sql"); 38 return Packages.org.apache.commons.logging.LogFactory.getLog(fname); 39 } 40 41 var SqlData = function(result) { 42 var columns = []; 43 this.values = {}; 44 45 for (var i=1; i<=result.getColumnCount(); i+=1) { 46 columns.push(result.getColumnName(i)); 47 } 48 49 this.next = function() { 50 for each (var key in columns) { 51 this.values[key] = result.getColumnItem(key); 52 } 53 return; 54 } 55 56 return this; 57 } 58 59 var quote = function(str) { 60 if (str === null) { 61 return str; 62 } 63 return "'" + str.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'"; 64 } 65 66 var value = function(obj) { 67 if (obj === null) { 68 return obj; 69 } 70 if (obj === undefined) { 71 obj = String(obj); 72 } 73 switch (obj.constructor) { 74 case Number: 75 return obj; 76 case String: 77 return quote(obj); 78 case Date: 79 return "from_unixtime(" + (obj.getTime() / 1000) + ")"; 80 case HopObject: 81 case Object: 82 return quote(obj.toSource()); 83 } 84 return quote(String(obj)); 85 } 86 87 var resolve = function(args) { 88 var sql = args[0]; 89 if (args.length > 1) { 90 var values = Array.prototype.splice.call(args, 1); 91 if (typeof values[0] === "object") { 92 values = values[0]; 93 } 94 sql = sql.replace(/\$(\w*)/g, function() { 95 return value(values[arguments[1]]); 96 }); 97 } 98 return sql; 99 } 100 101 /** 102 * 103 * @param {String} sql 104 * @returns {Object} 105 */ 106 this.execute = function(sql) { 107 sql = resolve(arguments); 108 log.info(sql); 109 var error; 110 var result = db.executeCommand(sql); 111 if (error = db.getLastError()) { 112 app.log(error); 113 } 114 return result; 115 } 116 117 /** 118 * @returns {String} 119 */ 120 this.retrieve = function() { 121 return log.info(query = resolve(arguments)); 122 } 123 124 /** 125 * 126 * @param {Function} callback 127 */ 128 this.traverse = function(callback) { 129 var rows = db.executeRetrieval(query); 130 if (rows && rows.next()) { 131 do { 132 var sql = new SqlData(rows); 133 sql.next(); 134 callback.call(sql.values, rows); 135 } while (record = rows.next()); 136 rows.release(); 137 } 138 return; 139 } 140 141 /** 142 * @return {String} 143 */ 144 this.toString = function() { 145 return query; 146 } 147 148 return this; 149 } 150