/plugins/dbmigrate/TableDefinition.cfc

http://raihan.googlecode.com/ · ColdFusion CFScript · 283 lines · 265 code · 18 blank · 0 comment · 26 complexity · c9154e0d090587c156e818eec3c25b58 MD5 · raw file

  1. <cfcomponent extends="Base">
  2. <cffunction name="init" returntype="TableDefinition" access="public">
  3. <cfargument name="adapter" type="any" required="yes" hint="database adapter">
  4. <cfargument name="name" type="string" required="yes" hint="table name in pluralized form">
  5. <cfargument name="force" type="boolean" required="no" default="true" hint="whether or not to drop table of same name before creating new one">
  6. <cfargument name="id" type="boolean" required="no" default="false" hint="if false, defines a table with no primary key">
  7. <cfargument name="primaryKey" type="string" required="no" default="id" hint="overrides default primary key">
  8. <cfscript>
  9. var loc = {};
  10. loc.args = "adapter,name,force";
  11. loc.iEnd = ListLen(loc.args);
  12. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  13. loc.argumentName = ListGetAt(loc.args,loc.i);
  14. if(StructKeyExists(arguments,loc.argumentName)) {
  15. this[loc.argumentName] = arguments[loc.argumentName];
  16. }
  17. }
  18. this.columns = ArrayNew(1);
  19. if(arguments.id && Len(arguments.primaryKey)) {
  20. column(columnName=arguments.primaryKey,columnType="primaryKey");
  21. }
  22. this.foreignKeys = ArrayNew(1);
  23. </cfscript>
  24. <cfreturn this>
  25. </cffunction>
  26. <cffunction name="column" returntype="void" access="public" hint="adds a column to table definition">
  27. <cfargument name="columnName" type="string" required="yes" hint="column name">
  28. <cfargument name="columnType" type="string" required="yes" hint="column type">
  29. <cfargument name="default" type="string" required="no" hint="default value">
  30. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  31. <cfargument name="limit" type="numeric" required="no" hint="character or integer size">
  32. <cfargument name="precision" type="numeric" required="no" hint="number of digits the column can hold">
  33. <cfargument name="scale" type="numeric" required="no" hint="number of digits that can be placed to the right of the decimal point (must be less than or equal to precision)">
  34. <cfscript>
  35. var loc = {};
  36. arguments.adapter = this.adapter;
  37. arguments.name = arguments.columnName;
  38. arguments.type = arguments.columnType;
  39. loc.column = CreateObject("component","ColumnDefinition").init(argumentCollection=arguments);
  40. ArrayAppend(this.columns,loc.column);
  41. </cfscript>
  42. </cffunction>
  43. <cffunction name="binary" returntype="void" access="public" hint="adds binary columns to table definition">
  44. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  45. <cfargument name="default" type="string" required="no" hint="default value">
  46. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  47. <cfscript>
  48. var loc = {};
  49. arguments.columnType = "binary";
  50. loc.iEnd = ListLen(arguments.columnNames);
  51. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  52. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  53. column(argumentCollection=arguments);
  54. }
  55. </cfscript>
  56. </cffunction>
  57. <cffunction name="boolean" returntype="void" access="public" hint="adds boolean columns to table definition">
  58. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  59. <cfargument name="default" type="string" required="no" hint="default value">
  60. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  61. <cfscript>
  62. var loc = {};
  63. arguments.columnType = "boolean";
  64. loc.iEnd = ListLen(arguments.columnNames);
  65. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  66. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  67. column(argumentCollection=arguments);
  68. }
  69. </cfscript>
  70. </cffunction>
  71. <cffunction name="date" returntype="void" access="public" hint="adds date columns to table definition">
  72. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  73. <cfargument name="default" type="string" required="no" hint="default value">
  74. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  75. <cfscript>
  76. var loc = {};
  77. arguments.columnType = "date";
  78. loc.iEnd = ListLen(arguments.columnNames);
  79. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  80. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  81. column(argumentCollection=arguments);
  82. }
  83. </cfscript>
  84. </cffunction>
  85. <cffunction name="datetime" returntype="void" access="public" hint="adds datetime columns to table definition">
  86. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  87. <cfargument name="default" type="string" required="no" hint="default value">
  88. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  89. <cfscript>
  90. var loc = {};
  91. arguments.columnType = "datetime";
  92. loc.iEnd = ListLen(arguments.columnNames);
  93. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  94. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  95. column(argumentCollection=arguments);
  96. }
  97. </cfscript>
  98. </cffunction>
  99. <cffunction name="decimal" returntype="void" access="public" hint="adds decimal columns to table definition">
  100. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  101. <cfargument name="default" type="string" required="no" hint="default value">
  102. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  103. <cfargument name="precision" type="numeric" required="no" hint="number of digits the column can hold">
  104. <cfargument name="scale" type="numeric" required="no" hint="number of digits that can be placed to the right of the decimal point (must be less than or equal to precision)">
  105. <cfscript>
  106. var loc = {};
  107. arguments.columnType = "decimal";
  108. loc.iEnd = ListLen(arguments.columnNames);
  109. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  110. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  111. column(argumentCollection=arguments);
  112. }
  113. </cfscript>
  114. </cffunction>
  115. <cffunction name="float" returntype="void" access="public" hint="adds float columns to table definition">
  116. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  117. <cfargument name="default" type="string" required="no" default="" hint="default value">
  118. <cfargument name="null" type="boolean" required="no" default="true" hint="whether nulls are allowed">
  119. <cfscript>
  120. var loc = {};
  121. arguments.columnType = "float";
  122. loc.iEnd = ListLen(arguments.columnNames);
  123. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  124. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  125. column(argumentCollection=arguments);
  126. }
  127. </cfscript>
  128. </cffunction>
  129. <cffunction name="integer" returntype="void" access="public" hint="adds integer columns to table definition">
  130. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  131. <cfargument name="limit" type="numeric" required="no" hint="integer size">
  132. <cfargument name="default" type="string" required="no" hint="default value">
  133. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  134. <cfscript>
  135. var loc = {};
  136. arguments.columnType = "integer";
  137. loc.iEnd = ListLen(arguments.columnNames);
  138. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  139. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  140. column(argumentCollection=arguments);
  141. }
  142. </cfscript>
  143. </cffunction>
  144. <cffunction name="string" returntype="void" access="public" hint="adds string columns to table definition">
  145. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  146. <cfargument name="limit" type="numeric" required="no" hint="character limit">
  147. <cfargument name="default" type="string" required="no" hint="default value">
  148. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  149. <cfscript>
  150. var loc = {};
  151. arguments.columnType = "string";
  152. loc.iEnd = ListLen(arguments.columnNames);
  153. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  154. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  155. column(argumentCollection=arguments);
  156. }
  157. </cfscript>
  158. </cffunction>
  159. <cffunction name="text" returntype="void" access="public" hint="adds text columns to table definition">
  160. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  161. <cfargument name="default" type="string" required="no" hint="default value">
  162. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  163. <cfscript>
  164. var loc = {};
  165. arguments.columnType = "text";
  166. loc.iEnd = ListLen(arguments.columnNames);
  167. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  168. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  169. column(argumentCollection=arguments);
  170. }
  171. </cfscript>
  172. </cffunction>
  173. <cffunction name="time" returntype="void" access="public" hint="adds time columns to table definition">
  174. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  175. <cfargument name="default" type="string" required="no" hint="default value">
  176. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  177. <cfscript>
  178. var loc = {};
  179. arguments.columnType = "time";
  180. loc.iEnd = ListLen(arguments.columnNames);
  181. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  182. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  183. column(argumentCollection=arguments);
  184. }
  185. </cfscript>
  186. </cffunction>
  187. <cffunction name="timestamp" returntype="void" access="public" hint="adds timestamp columns to table definition">
  188. <cfargument name="columnNames" type="string" required="yes" hint="one or more column names, comma delimited">
  189. <cfargument name="default" type="string" required="no" hint="default value">
  190. <cfargument name="null" type="boolean" required="no" hint="whether nulls are allowed">
  191. <cfscript>
  192. var loc = {};
  193. arguments.columnType = "timestamp";
  194. loc.iEnd = ListLen(arguments.columnNames);
  195. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  196. arguments.columnName = ListGetAt(arguments.columnNames,loc.i);
  197. column(argumentCollection=arguments);
  198. }
  199. </cfscript>
  200. </cffunction>
  201. <cffunction name="timestamps" returntype="void" access="public" hint="adds CFWheels convention automatic timestamp and soft delete columns to table definition">
  202. <cfscript>
  203. timestamp(columnNames="createdat,updatedat,deletedat",null=true);
  204. </cfscript>
  205. </cffunction>
  206. <cffunction name="references" returntype="void" access="public" hint="adds integer reference columns to table definition and creates foreign key constraints">
  207. <cfargument name="referenceNames" type="string" required="yes" hint="one or more reference names (singular of referenced tables), comma delimited. eg. referenceNames=page will create a column pageId that references table:pages, column:id">
  208. <cfargument name="default" type="string" required="no" default="NULL" hint="default value">
  209. <cfargument name="null" type="boolean" required="no" default="true" hint="whether nulls are allowed">
  210. <cfargument name="polymorphic" type="boolean" required="no" default="false" hint="whether or not to create an Id/Type pair of columns for a polymorphic relationship">
  211. <cfargument name="foreignKey" type="boolean" required="no" default="true" hint="whether or not to create a foreign key constraint">
  212. <cfscript>
  213. var loc = {};
  214. loc.iEnd = ListLen(arguments.referenceNames);
  215. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  216. loc.referenceName = ListGetAt(arguments.referenceNames,loc.i);
  217. column(columnName = loc.referenceName & "id",columnType="integer",default=arguments.default,null=arguments.null);
  218. if(arguments.polymorphic) {
  219. column(columnName=loc.referenceName & "type",columnType="string");
  220. }
  221. if(arguments.foreignKey && !arguments.polymorphic) {
  222. loc.referenceTable = pluralize(loc.referenceName);
  223. loc.foreignKey = CreateObject("component","ForeignKeyDefinition").init(adapter=this.adapter,table=this.name,referenceTable=loc.referenceTable,column="#loc.referenceName#id",referenceColumn="id");
  224. ArrayAppend(this.foreignKeys,loc.foreignKey);
  225. }
  226. }
  227. </cfscript>
  228. </cffunction>
  229. <cffunction name="create" returntype="void" access="public" hint="creates the table in the database">
  230. <cfscript>
  231. if(this.force) {
  232. $execute(this.adapter.dropTable(this.name));
  233. announce("Dropped table #LCase(this.name)#");
  234. }
  235. $execute(this.adapter.createTable(name=this.name,columns=this.columns,foreignKeys=this.foreignKeys));
  236. announce("Created table #LCase(this.name)#");
  237. loc.iEnd = ArrayLen(this.foreignKeys);
  238. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  239. announce("--> added foreign key #this.foreignKeys[loc.i].name#");
  240. }
  241. </cfscript>
  242. </cffunction>
  243. <cffunction name="change" returntype="void" access="public" hint="alters existing table in the database">
  244. <cfargument name="addColumns" type="boolean" required="false" default="false" hint="if true, attempt to add new columns, else check whether column exists to determine whether to add or update">
  245. <cfscript>
  246. var loc = {};
  247. loc.existingColumns = $getColumns(this.name);
  248. loc.iEnd = ArrayLen(this.columns);
  249. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  250. if(arguments.addColumns || !ListFindNoCase(loc.existingColumns,this.columns[loc.i].name)) {
  251. $execute(this.adapter.addColumnToTable(name=this.name,column=this.columns[loc.i]));
  252. announce("Added column #this.columns[loc.i].name# to table #this.name#");
  253. } else {
  254. $execute(this.adapter.changeColumnInTable(name=this.name,column=this.columns[loc.i]));
  255. announce("Changed column #this.columns[loc.i].name# in table #this.name#");
  256. }
  257. }
  258. loc.iEnd = ArrayLen(this.foreignKeys);
  259. for (loc.i=1; loc.i <= loc.iEnd; loc.i++) {
  260. $execute(this.adapter.addForeignKeyToTable(name=this.name,foreignKey=this.foreignKeys[loc.i]));
  261. announce("Added foreign key #this.foreignKeys[loc.i].name# to table #this.name#");
  262. }
  263. </cfscript>
  264. </cffunction>
  265. </cfcomponent>