1:<!--- 2: $Id$ 3: 4: CachedQueryManager: Utility methods for manipulating ColdFusion's cached-queries store 5: 6: This component uses the following Coldfusion classes: 7: 8: coldfusion.util.LruCache 9: coldfusion.server.ServiceFactory 10: coldfusion.server.DataSourceService 11: coldfusion.sql.Executive 12: coldfusion.tagext.sql.CachedQuery 13: 14: ==================================================================== 15: 16: Copyright (c) 2006 Asif Tamuri. All rights reserved. 17: 18: Redistribution and use in source and binary forms, with or without 19: modification, are permitted provided that the following conditions 20: are met: 21: 22: 1. Redistributions of source code must retain the above copyright 23: notice, this list of conditions and the following disclaimer. 24: 25: 2. Redistributions in binary form must reproduce the above copyright 26: notice, this list of conditions and the following disclaimer in 27: the documentation and/or other materials provided with the 28: distribution. 29: 30: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 31: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 33: DISCLAIMED. IN NO EVENT SHALL THE SOFTWARE'S AUTHORS OR ITS 34: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 37: USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 38: ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 39: OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 40: OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 41: SUCH DAMAGE. 42: 43: ==================================================================== 44:---> 45:<cfcomponent displayname="CachedQueryManager" 46: hint="Utility methods for manipulating ColdFusion's cached-queries store"> 47: 48: <!--- PROPERTIES ---> 49: <cfset variables.KEY_FIELD = "key" /> 50: <cfset variables.HITS_FIELD = "hits" /> 51: <cfset variables.PENALTY_FIELD = "penalty" /> 52: <cfset variables.RANK_FIELD = "rank" /> 53: <cfset variables.CREATION_TIME_FIELD = "creation_time" /> 54: <cfset variables.NEWEST_ENTRY_FIELD = "newest" /> 55: <cfset variables.OLDER_FIELD = "older" /> 56: <cfset variables.VALUE_FIELD = "value" /> 57: <cfset variables.QUERY_CACHE_FIELD = "query_cache" /> 58: 59: <cfset variables.LruCacheClassName = "coldfusion.util.LruCache" /> 60: <cfset variables.ServiceFactoryClassName = "coldfusion.server.ServiceFactory" /> 61: 62: <!--- CONSTRUCTOR ---> 63: <cffunction name="init" access="public" returntype="CachedQueryManager" output="no" hint="Returns instance"> 64: <cfreturn this /> 65: </cffunction> 66: 67: <!--- PUBLIC METHODS ---> 68: <cffunction name="getAll" access="public" returntype="query" output="no" hint="Returns all queries currently cached by Coldfusion"> 69: <!--- Create a query in which to store results ---> 70: <cfset var cachedQueries = queryNew("#variables.KEY_FIELD#,#variables.HITS_FIELD#,#variables.RANK_FIELD#,#variables.PENALTY_FIELD#,#variables.CREATION_TIME_FIELD#") /> 71: <!--- Query is filled by reference ---> 72: <cfset populateEntriesQuery(cachedQueries) /> 73: <cfreturn cachedQueries /> 74: </cffunction> 75: 76: <cffunction name="remove" access="public" returntype="void" output="no" hint="Removes a query from ColdFusion's cache"> 77: <cfargument name="key" required="yes" type="string" hint="The cached-query's key. Use getAll() to get full list of keys." /> 78: <cfset getLruCache().remove(arguments.key) /> 79: </cffunction> 80: 81: <cffunction name="clear" access="public" returntype="void" output="no" hint="Calls cfobjectcache tag"> 82: <cfobjectcache action="clear" /> 83: </cffunction> 84: 85: <!--- PRIVATE METHODS ---> 86: <cffunction name="populateEntriesQuery" access="private" returntype="void" output="no"> 87: <cfargument name="entries" required="yes" type="query" /> 88: 89: <cfset var tmp = arrayNew(1) /> 90: <cfset var newestEntry = 0 /> 91: <cfset var lruClass = tmp.getClass().forName(variables.LruCacheClassName) /> 92: <cfset var query_cache = getLruCache() /> 93: 94: <cfset var newestEntryField = lruClass.getDeclaredField(variables.NEWEST_ENTRY_FIELD) /> 95: <cfset newestEntryField.setAccessible(javaCast("boolean", true)) /> 96: <cfset newestEntry = newestEntryField.get(query_cache) /> 97: 98: <cfif isDefined("newestEntry")> 99: <cfset addEntryFieldsToQuery(newestEntry, arguments.entries) /> 100: </cfif> 101: </cffunction> 102: 103: <cffunction name="addEntryFieldsToQuery" access="private" returntype="void" output="no"> 104: <cfargument name="entry" required="yes" /> 105: <cfargument name="entries" required="yes" type="query" /> 106: 107: <cfset var keyField = arguments.entry.getClass().getDeclaredField(variables.KEY_FIELD) /> 108: <cfset var hitsField = arguments.entry.getClass().getDeclaredField(variables.HITS_FIELD) /> 109: <cfset var olderEntryField = arguments.entry.getClass().getDeclaredField(variables.OLDER_FIELD) /> 110: <cfset var penaltyField = arguments.entry.getClass().getDeclaredField(variables.PENALTY_FIELD) /> 111: <cfset var valueField = arguments.entry.getClass().getDeclaredField(variables.VALUE_FIELD) /> 112: 113: <cfset var rowCount = queryAddRow(arguments.entries) /> 114: 115: <cfset keyField.setAccessible(javaCast("boolean", true)) /> 116: <cfset hitsField.setAccessible(javaCast("boolean", true)) /> 117: <cfset olderEntryField.setAccessible(javaCast("boolean", true)) /> 118: <cfset penaltyField.setAccessible(javaCast("boolean", true)) /> 119: <cfset valueField.setAccessible(javaCast("boolean", true)) /> 120: 121: <cfset querySetCell(arguments.entries, variables.KEY_FIELD, keyField.get(arguments.entry).toString()) /> 122: <cfset querySetCell(arguments.entries, variables.HITS_FIELD, hitsField.get(arguments.entry).toString()) /> 123: <cfset querySetCell(arguments.entries, variables.PENALTY_FIELD, penaltyField.get(arguments.entry).toString()) /> 124: <cfset querySetCell(arguments.entries, variables.RANK_FIELD, rowCount) /> 125: <cfset querySetCell(arguments.entries, variables.CREATION_TIME_FIELD, valueField.get(arguments.entry).getCreationTime()) /> 126: 127: <cfif olderEntryField.get(arguments.entry) neq ""> 128: <cfset addEntryFieldsToQuery(olderEntryField.get(arguments.entry), arguments.entries) /> 129: </cfif> 130: </cffunction> 131: 132: <cffunction name="getLruCache" access="private" returntype="any" output="no"> 133: <cfset var factory = CreateObject("java", variables.ServiceFactoryClassName) /> 134: <cfset var dss = factory.getDataSourceService() /> 135: <cfset var queryCacheField = dss.getClass().getDeclaredField(variables.QUERY_CACHE_FIELD) /> 136: <cfset queryCacheField.setAccessible(true) /> 137: <cfreturn queryCacheField.get(dss) /> 138: </cffunction> 139: 140:</cfcomponent> 141: