PageRenderTime 34ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/wheels/model/query.cfm

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