PageRenderTime 44ms CodeModel.GetById 38ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 1ms

/wheels/model/query.cfm

http://cfwheels.googlecode.com/
ColdFusion | 245 lines | 231 code | 14 blank | 0 comment | 15 complexity | 8e50686a9373059e17980c5cbd56fbb5 MD5 | raw file
  1<cffunction name="distinct" returntype="component" output="false" access="public">
  2	<cfset variables.wheels.instance.query.distinct = true>
  3	<cfreturn this />
  4</cffunction>
  5
  6<cffunction name="select" returntype="component" output="false" access="public">
  7	<cfargument name="properties" type="string" required="true" />
  8	<cfset variables.wheels.instance.query.select = ListAppend(variables.wheels.instance.query.select, $listClean(arguments.properties)) />
  9	<cfreturn this />
 10</cffunction>
 11
 12<cffunction name="include" returntype="component" output="false" access="public">
 13	<cfargument name="associations" type="string" required="false" default="" />
 14	<cfscript>
 15		arguments.associations = $listClean(arguments.associations);
 16		// we could also have an association argument
 17		if (!Len(arguments.associations) && StructKeyExists(arguments, "association"))
 18			arguments.associations = $listClean(arguments.association);
 19		variables.wheels.instance.query.include = ListAppend(variables.wheels.instance.query.include, arguments.associations);
 20	</cfscript>
 21	<cfreturn this />
 22</cffunction>
 23
 24<cffunction name="where" returntype="component" output="false" access="public">
 25	<cfargument name="property" type="string" required="false" default="" />
 26	<cfset variables.wheels.instance.query.where = $registerOperation(argumentCollection=arguments, type="where", container=variables.wheels.instance.query.where)>
 27	<cfreturn this />
 28</cffunction>
 29
 30<cffunction name="and" returntype="component" output="false" access="public">
 31	<cfargument name="property" type="string" required="false" default="" />
 32	<cfset variables.wheels.instance.query.where = $registerOperation(argumentCollection=arguments, type="and", container=variables.wheels.instance.query.where)>
 33	<cfreturn this />
 34</cffunction>
 35
 36<cffunction name="or" returntype="component" output="false" access="public">
 37	<cfargument name="property" type="string" required="false" default="" />
 38	<cfset variables.wheels.instance.query.where = $registerOperation(argumentCollection=arguments, type="or", container=variables.wheels.instance.query.where)>
 39	<cfreturn this />
 40</cffunction>
 41
 42<cffunction name="group" returntype="component" output="false" access="public">
 43	<cfargument name="properties" type="string" required="true" />
 44	<cfset variables.wheels.instance.query.group = ListAppend(variables.wheels.instance.query.group, $listClean(arguments.properties)) />
 45	<cfreturn this />
 46</cffunction>
 47
 48<cffunction name="order" returntype="component" output="false" access="public">
 49	<cfargument name="property" type="string" required="true" />
 50	<cfargument name="direction" type="string" required="false" default="ASC" />
 51	<cfscript>
 52		var loc = {};
 53		ArrayAppend(variables.wheels.instance.query.order, StructNew());
 54		loc.length = ArrayLen(variables.wheels.instance.query.order);
 55		variables.wheels.instance.query.order[loc.length].property = arguments.property;
 56		variables.wheels.instance.query.order[loc.length].direction = UCase(arguments.direction);
 57	</cfscript>
 58	<cfreturn this />
 59</cffunction>
 60
 61<cffunction name="page" returntype="component" output="false" access="public">
 62	<cfargument name="value" type="numeric" required="true" />
 63	<cfset variables.wheels.instance.query.page = arguments.value />
 64	<cfreturn this />
 65</cffunction>
 66
 67<cffunction name="perPage" returntype="component" output="false" access="public">
 68	<cfargument name="value" type="numeric" required="true" />
 69	<cfset variables.wheels.instance.query.perpage = arguments.value />
 70	<cfreturn this />
 71</cffunction>
 72
 73<cffunction name="maxRows" returntype="component" output="false" access="public">
 74	<cfargument name="value" type="numeric" required="true" />
 75	<cfset variables.wheels.instance.query.maxrows = arguments.value />
 76	<cfreturn this />
 77</cffunction>
 78
 79<cffunction name="$registerOperation" returntype="array" output="false" access="public">
 80	<cfargument name="type" type="string" required="true" />
 81	<cfargument name="property" type="string" required="true" />
 82	<cfargument name="container" type="array" required="true" />
 83	<cfscript>
 84		var loc = {};
 85
 86		loc.operationList = ArrayToList(variables.wheels.class.operations);
 87		loc.exclusionList = ListPrepend(loc.operationList, "type,property,container,value,operator,negate");
 88		
 89		if (Len(arguments.property) || StructKeyExists(arguments, "sql"))
 90		{
 91			// make sure we have an operator and value
 92			for (loc.item in arguments)
 93			{
 94				if (ListFindNoCase(loc.operationList, loc.item))
 95				{
 96					arguments.value = arguments[loc.item];
 97					if (FindNoCase("not", loc.item))
 98					{
 99						loc.item = LCase(ReplaceNoCase(loc.item, "not", ""));
100						arguments.negate = true;
101					}
102					arguments.operator = loc.item;
103					StructDelete(arguments, loc.item);
104					break;
105				}
106			}
107			
108			if (StructKeyExists(arguments, "operator") && StructKeyExists(arguments, "value"))
109			{
110				if (application.wheels.showErrorInformation && ListFindNoCase("or,and", arguments.type) && !ArrayLen(arguments.container))
111					$throw(type="Wheels.IncorrectQueryMethodChaining", message="The `where`method must be called before `or` or `and`.");
112				arguments.container = $invoke(method="$#arguments.operator#Operation", argumentCollection=arguments);
113			}
114			else if (StructKeyExists(arguments, "operator"))
115			{
116				$throw(type="Wheels.OperationNotValid", message="The operation `#arguments.operator#` is not valid. Please use any of these `#ArrayToList(variables.wheels.class.operators)#`.");
117			}
118			else
119			{
120				$throw(type="Wheels.OperationNotFound", message="An operation could not be found. Please use any of these `#ArrayToList(variables.wheels.class.operators)#`.");
121			}
122		}
123		// loop through the properties and add in our auto eql clauses
124		if (!StructKeyExists(arguments, "$auto"))
125		{
126			// AFAIK there is now way to reference the arguments scope as an array
127			// and retrieve the name of the argument and referencing the struct directly
128			// dooesn't guarentee the order.
129			// because of that we will use StructKeyArray() and ArraySort()
130			// to maintain some sort of order
131			loc.keys = StructKeyArray(arguments);
132			ArraySort(loc.keys, "textnocase");
133			loc.iKeys = ArrayLen(loc.keys);
134			for (loc.i=1; loc.i LTE loc.iKeys; loc.i++)
135			{
136				loc.item = loc.keys[loc.i];
137				if (!ListFindNoCase(loc.exclusionList, loc.item))
138				{
139					loc.type = "and";
140					if (arguments.type == "where" && ArrayIsEmpty(arguments.container))
141						loc.type = "where";
142					if (!ListFindNoCase(loc.exclusionList, loc.item))
143						arguments.container = $registerOperation(type=loc.type, property=loc.item, eql=arguments[loc.item], container=arguments.container, $auto=true);
144				}
145			}
146		}
147	</cfscript>
148	<cfreturn arguments.container />
149</cffunction>
150
151<cffunction name="$eqlOperation" returntype="array" access="public" output="false">
152	<cfreturn $addOperation(argumentCollection=arguments) />
153</cffunction>
154
155<cffunction name="$greaterThanOperation" returntype="array" access="public" output="false">
156	<cfreturn $addOperation(argumentCollection=arguments) />
157</cffunction>
158
159<cffunction name="$greaterThanEqlOperation" returntype="array" access="public" output="false">
160	<cfreturn $addOperation(argumentCollection=arguments) />
161</cffunction>
162
163<cffunction name="$lessThanOperation" returntype="array" access="public" output="false">
164	<cfreturn $addOperation(argumentCollection=arguments) />
165</cffunction>
166
167<cffunction name="$lessThanEqlOperation" returntype="array" access="public" output="false">
168	<cfreturn $addOperation(argumentCollection=arguments) />
169</cffunction>
170
171<cffunction name="$inOperation" returntype="array" access="public" output="false">
172	<cfset arguments.value = $ensureArray(arguments.value) />
173	<cfreturn $addOperation(argumentCollection=arguments) />
174</cffunction>
175
176<cffunction name="$betweenOperation" returntype="array" access="public" output="false">
177	<cfset arguments.value = $ensureArray(argumentCollection=arguments, length=2) />
178	<cfreturn $addOperation(argumentCollection=arguments) />
179</cffunction>
180
181<cffunction name="$nullOperation" returntype="array" access="public" output="false">
182	<cfscript>
183		if (IsBoolean(arguments.value) && !arguments.value)
184			arguments.negate = true;
185		arguments.value = "";
186		arguments.container = $addOperation(argumentCollection=arguments);
187	</cfscript>
188	<cfreturn arguments.container />
189</cffunction>
190
191<cffunction name="$sqlOperation" returntype="array" access="public" output="false">
192	<cfreturn $addOperation(argumentCollection=arguments) />
193</cffunction>
194
195<cffunction name="$ensureArray" returntype="array" access="public" output="false">
196	<cfargument name="value" type="any" required="true" />
197	<cfargument name="length" type="numeric" required="false" default="0" />
198	<cfscript>
199		if (IsSimpleValue(arguments.value))
200			arguments.value = ListToArray($listClean(arguments.value));
201		
202		if (arguments.length gt 0 && ArrayLen(arguments.value) != arguments.length)
203			$throw(type="Wheels.InvalidQueryPropertyValue", message="The value provided for the property `#arguments.property#` must be a list or array with exactly `#arguments.length#` values.");
204	</cfscript>
205	<cfreturn arguments.value />
206</cffunction>
207
208<cffunction name="$addOperation" returntype="array" access="public" output="false">
209	<cfscript>
210		var loc = {};
211		ArrayAppend(arguments.container, StructNew());
212		loc.length = ArrayLen(arguments.container);
213		arguments.container[loc.length].type = arguments.type;
214		if (Len(arguments.property))
215			arguments.container[loc.length].property = arguments.property;
216		arguments.container[loc.length].operation = arguments.operator;
217		arguments.container[loc.length].value = arguments.value;
218		arguments.container[loc.length].negate = false;
219		if (StructKeyExists(arguments, "negate") && IsBoolean(arguments.negate) && arguments.negate)
220			arguments.container[loc.length].negate = true;
221	</cfscript>
222	<cfreturn arguments.container />
223</cffunction>
224
225<cffunction name="clearQuery" returntype="component" access="public" output="false">
226	<cfscript>
227		variables.wheels.instance.query = {};
228		variables.wheels.instance.query.distinct = false;
229		variables.wheels.instance.query.select = "";
230		variables.wheels.instance.query.include = "";
231		variables.wheels.instance.query.where = [];
232		variables.wheels.instance.query.group = "";
233		variables.wheels.instance.query.order = [];
234		variables.wheels.instance.query.having = [];
235		variables.wheels.instance.query.page = 0;
236		variables.wheels.instance.query.perPage = 0;
237		variables.wheels.instance.query.maxRows = -1;
238	</cfscript>
239	<cfreturn this />
240</cffunction>
241
242<cffunction name="toQuery" returntype="struct" access="public" output="false">
243	<cfreturn variables.wheels.instance.query />
244</cffunction>
245