PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/wheels/model/initialization.cfm

http://cfwheels.googlecode.com/
ColdFusion | 230 lines | 207 code | 23 blank | 0 comment | 42 complexity | 4381885185c5c59dc0a1ffe8515852ba MD5 | raw file
Possible License(s): Apache-2.0, CPL-1.0
  1. <cffunction name="$initModelClass" returntype="any" access="public" output="false">
  2. <cfargument name="name" type="string" required="true">
  3. <cfargument name="path" type="string" required="true">
  4. <cfscript>
  5. var loc = {};
  6. variables.wheels = {};
  7. variables.wheels.class = {};
  8. variables.wheels.class.alias = arguments.name;
  9. variables.wheels.class.modelName = arguments.name;
  10. variables.wheels.class.path = arguments.path;
  11. // if our name has pathing in it, remove it and add it to the end of of the $class.path variable
  12. if (Find("/", arguments.name))
  13. {
  14. variables.wheels.class.modelName = ListLast(arguments.name, "/");
  15. variables.wheels.class.path = ListAppend(arguments.path, ListDeleteAt(arguments.name, ListLen(arguments.name, "/"), "/"), "/");
  16. }
  17. variables.wheels.class.RESQLAs = "[[:space:]]AS[[:space:]][A-Za-z1-9]+";
  18. variables.wheels.class.RESQLOperators = "((?: (?:NOT )?LIKE)|(?: (?:NOT )?IN)|(?: IS(?: NOT)?)|(?:<>)|(?:<=)|(?:>=)|(?:!=)|(?:!<)|(?:!>)|=|<|>)";
  19. variables.wheels.class.RESQLWhere = "(#variables.wheels.class.RESQLOperators# ?)(\('.+?'\)|\((-?[0-9\.],?)+\)|'.+?'()|''|(-?[0-9\.]+)()|NULL)(($|\)| (AND|OR)))";
  20. variables.wheels.class.aliases = {};
  21. variables.wheels.class.mapping = {};
  22. variables.wheels.class.properties = {};
  23. variables.wheels.class.accessibleProperties = {};
  24. variables.wheels.class.calculatedProperties = {};
  25. variables.wheels.class.associations = {};
  26. variables.wheels.class.callbacks = {};
  27. variables.wheels.class.keys = "";
  28. variables.wheels.class.connection = {datasource=application.wheels.dataSourceName, username=application.wheels.dataSourceUserName, password=application.wheels.dataSourcePassword};
  29. variables.wheels.class.automaticValidations = application.wheels.automaticValidations;
  30. setTableNamePrefix(get("tableNamePrefix"));
  31. table(LCase(pluralize(variables.wheels.class.modelName)));
  32. loc.callbacks = "afterNew,afterFind,afterInitialization,beforeDelete,afterDelete,beforeSave,afterSave,beforeCreate,afterCreate,beforeUpdate,afterUpdate,beforeValidation,afterValidation,beforeValidationOnCreate,afterValidationOnCreate,beforeValidationOnUpdate,afterValidationOnUpdate";
  33. loc.iEnd = ListLen(loc.callbacks);
  34. for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
  35. variables.wheels.class.callbacks[ListGetAt(loc.callbacks, loc.i)] = ArrayNew(1);
  36. loc.validations = "onSave,onCreate,onUpdate";
  37. loc.iEnd = ListLen(loc.validations);
  38. for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
  39. variables.wheels.class.validations[ListGetAt(loc.validations, loc.i)] = ArrayNew(1);
  40. // run developer's init method if it exists
  41. if (StructKeyExists(variables, "init"))
  42. init();
  43. // make sure that the tablename has the respected prefix
  44. table(getTableNamePrefix() & tableName());
  45. // load the database adapter
  46. variables.wheels.class.adapter = $createObjectFromRoot(path="#application.wheels.wheelsComponentPath#", fileName="Connection", method="init", datasource="#variables.wheels.class.connection.datasource#", username="#variables.wheels.class.connection.username#", password="#variables.wheels.class.connection.password#");
  47. // get columns for the table
  48. loc.columns = variables.wheels.class.adapter.$getColumns(tableName());
  49. variables.wheels.class.propertyList = "";
  50. variables.wheels.class.columnList = "";
  51. loc.processedColumns = "";
  52. loc.iEnd = loc.columns.recordCount;
  53. for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
  54. {
  55. // set up properties and column mapping
  56. if (!ListFind(loc.processedColumns, loc.columns["column_name"][loc.i]))
  57. {
  58. loc.property = loc.columns["column_name"][loc.i]; // default the column to map to a property with the same name
  59. for (loc.key in variables.wheels.class.mapping)
  60. {
  61. if (StructKeyExists(variables.wheels.class.mapping[loc.key], "type") and variables.wheels.class.mapping[loc.key].type == "column" && variables.wheels.class.mapping[loc.key].value == loc.property)
  62. {
  63. // developer has chosen to map this column to a property with a different name so set that here
  64. loc.property = loc.key;
  65. break;
  66. }
  67. }
  68. loc.type = SpanExcluding(loc.columns["type_name"][loc.i], "( ");
  69. // set the info we need for each property
  70. variables.wheels.class.properties[loc.property] = {};
  71. variables.wheels.class.properties[loc.property].dataType = loc.type;
  72. variables.wheels.class.properties[loc.property].type = variables.wheels.class.adapter.$getType(loc.type, loc.columns["decimal_digits"][loc.i]);
  73. variables.wheels.class.properties[loc.property].column = loc.columns["column_name"][loc.i];
  74. variables.wheels.class.properties[loc.property].scale = loc.columns["decimal_digits"][loc.i];
  75. // get a boolean value for whether this column can be set to null or not
  76. // if we don't get a boolean back we try to translate y/n to proper boolean values in cfml (yes/no)
  77. variables.wheels.class.properties[loc.property].nullable = Trim(loc.columns["is_nullable"][loc.i]);
  78. if (!IsBoolean(variables.wheels.class.properties[loc.property].nullable))
  79. variables.wheels.class.properties[loc.property].nullable = ReplaceList(variables.wheels.class.properties[loc.property].nullable, "N,Y", "No,Yes");
  80. variables.wheels.class.properties[loc.property].size = loc.columns["column_size"][loc.i];
  81. variables.wheels.class.properties[loc.property].label = Humanize(loc.property);
  82. variables.wheels.class.properties[loc.property].validationtype = variables.wheels.class.adapter.$getValidationType(variables.wheels.class.properties[loc.property].type);
  83. if (StructKeyExists(variables.wheels.class.mapping, loc.property)) {
  84. if (StructKeyExists(variables.wheels.class.mapping[loc.property], "label"))
  85. variables.wheels.class.properties[loc.property].label = variables.wheels.class.mapping[loc.property].label;
  86. if (StructKeyExists(variables.wheels.class.mapping[loc.property], "defaultValue"))
  87. variables.wheels.class.properties[loc.property].defaultValue = variables.wheels.class.mapping[loc.property].defaultValue;
  88. }
  89. if (loc.columns["is_primarykey"][loc.i])
  90. {
  91. setPrimaryKey(loc.property);
  92. }
  93. else if (variables.wheels.class.automaticValidations and not ListFindNoCase("#application.wheels.timeStampOnCreateProperty#,#application.wheels.timeStampOnUpdateProperty#,#application.wheels.softDeleteProperty#", loc.property))
  94. {
  95. // set nullable validations if the developer has not
  96. loc.defaultValidationsAllowBlank = variables.wheels.class.properties[loc.property].nullable;
  97. if (!variables.wheels.class.properties[loc.property].nullable and !Len(loc.columns["column_default_value"][loc.i]) and !$validationExists(property=loc.property, validation="validatesPresenceOf"))
  98. {
  99. validatesPresenceOf(properties=loc.property);
  100. }
  101. // always allowblank if a database default or validatesPresenceOf() has been set
  102. if (Len(loc.columns["column_default_value"][loc.i]) or $validationExists(property=loc.property, validation="validatesPresenceOf"))
  103. loc.defaultValidationsAllowBlank = true;
  104. // set length validations if the developer has not
  105. if (variables.wheels.class.properties[loc.property].validationtype eq "string" and !$validationExists(property=loc.property, validation="validatesLengthOf"))
  106. validatesLengthOf(properties=loc.property, allowBlank=loc.defaultValidationsAllowBlank, maximum=variables.wheels.class.properties[loc.property].size);
  107. // set numericality validations if the developer has not
  108. if (ListFindNoCase("integer,float", variables.wheels.class.properties[loc.property].validationtype) and !$validationExists(property=loc.property, validation="validatesNumericalityOf"))
  109. validatesNumericalityOf(properties=loc.property, allowBlank=loc.defaultValidationsAllowBlank, onlyInteger=(variables.wheels.class.properties[loc.property].validationtype eq "integer"));
  110. // set date validations if the developer has not (checks both dates or times as per the IsDate() function)
  111. if (variables.wheels.class.properties[loc.property].validationtype eq "datetime" and !$validationExists(property=loc.property, validation="validatesFormatOf"))
  112. validatesFormatOf(properties=loc.property, allowBlank=loc.defaultValidationsAllowBlank, type="date");
  113. }
  114. variables.wheels.class.propertyList = ListAppend(variables.wheels.class.propertyList, loc.property);
  115. variables.wheels.class.columnList = ListAppend(variables.wheels.class.columnList, variables.wheels.class.properties[loc.property].column);
  116. loc.processedColumns = ListAppend(loc.processedColumns, loc.columns["column_name"][loc.i]);
  117. }
  118. }
  119. // raise error when no primary key has been defined for the table
  120. if (!Len(primaryKeys()))
  121. {
  122. $throw(type="Wheels.NoPrimaryKey", message="No primary key exists on the `#tableName()#` table.", extendedInfo="Set an appropriate primary key on the `#tableName()#` table.");
  123. }
  124. // add calculated properties
  125. variables.wheels.class.calculatedPropertyList = "";
  126. for (loc.key in variables.wheels.class.mapping)
  127. {
  128. if (StructKeyExists(variables.wheels.class.mapping[loc.key], "type") and variables.wheels.class.mapping[loc.key].type != "column")
  129. {
  130. variables.wheels.class.calculatedPropertyList = ListAppend(variables.wheels.class.calculatedPropertyList, loc.key);
  131. variables.wheels.class.calculatedProperties[loc.key] = {};
  132. variables.wheels.class.calculatedProperties[loc.key][variables.wheels.class.mapping[loc.key].type] = variables.wheels.class.mapping[loc.key].value;
  133. }
  134. }
  135. // set up soft deletion and time stamping if the necessary columns in the table exist
  136. if (Len(application.wheels.softDeleteProperty) && StructKeyExists(variables.wheels.class.properties, application.wheels.softDeleteProperty))
  137. {
  138. variables.wheels.class.softDeletion = true;
  139. variables.wheels.class.softDeleteColumn = variables.wheels.class.properties[application.wheels.softDeleteProperty].column;
  140. }
  141. else
  142. {
  143. variables.wheels.class.softDeletion = false;
  144. }
  145. if (Len(application.wheels.timeStampOnCreateProperty) && StructKeyExists(variables.wheels.class.properties, application.wheels.timeStampOnCreateProperty))
  146. {
  147. variables.wheels.class.timeStampingOnCreate = true;
  148. variables.wheels.class.timeStampOnCreateProperty = application.wheels.timeStampOnCreateProperty;
  149. }
  150. else
  151. {
  152. variables.wheels.class.timeStampingOnCreate = false;
  153. }
  154. if (Len(application.wheels.timeStampOnUpdateProperty) && StructKeyExists(variables.wheels.class.properties, application.wheels.timeStampOnUpdateProperty))
  155. {
  156. variables.wheels.class.timeStampingOnUpdate = true;
  157. variables.wheels.class.timeStampOnUpdateProperty = application.wheels.timeStampOnUpdateProperty;
  158. }
  159. else
  160. {
  161. variables.wheels.class.timeStampingOnUpdate = false;
  162. }
  163. </cfscript>
  164. <cfreturn this>
  165. </cffunction>
  166. <cffunction name="$initModelObject" returntype="any" access="public" output="false">
  167. <cfargument name="name" type="string" required="true">
  168. <cfargument name="properties" type="any" required="true">
  169. <cfargument name="persisted" type="boolean" required="true">
  170. <cfargument name="row" type="numeric" required="false" default="1">
  171. <cfargument name="base" type="boolean" required="false" default="true">
  172. <cfargument name="useFilterLists" type="boolean" required="false" default="true">
  173. <cfscript>
  174. var loc = {};
  175. variables.wheels = {};
  176. variables.wheels.instance = {};
  177. variables.wheels.instance.errors = [];
  178. // keep a unique identifier for each model created in case we need it for nested properties
  179. variables.wheels.instance.tickCountId = GetTickCount().toString(); // make sure we have it in milliseconds
  180. // copy class variables from the object in the application scope
  181. if (!StructKeyExists(variables.wheels, "class"))
  182. variables.wheels.class = $namedReadLock(name="classLock", object=application.wheels.models[arguments.name], method="$classData");
  183. // setup object properties in the this scope
  184. if (IsQuery(arguments.properties) && arguments.properties.recordCount != 0)
  185. arguments.properties = $queryRowToStruct(argumentCollection=arguments);
  186. if (IsStruct(arguments.properties) && !StructIsEmpty(arguments.properties))
  187. $setProperties(properties=arguments.properties, setOnModel=true, $useFilterLists=arguments.useFilterLists);
  188. if (arguments.persisted)
  189. $updatePersistedProperties();
  190. </cfscript>
  191. <cfreturn this>
  192. </cffunction>
  193. <cffunction name="$classData" returntype="struct" access="public" output="false">
  194. <cfreturn variables.wheels.class>
  195. </cffunction>
  196. <cffunction name="$softDeletion" returntype="boolean" access="public" output="false">
  197. <cfreturn variables.wheels.class.softDeletion>
  198. </cffunction>
  199. <cffunction name="$softDeleteColumn" returntype="string" access="public" output="false">
  200. <cfreturn variables.wheels.class.softDeleteColumn>
  201. </cffunction>