PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/wheels/model/adapters/Base.cfc

http://cfwheels.googlecode.com/
ColdFusion CFScript | 273 lines | 246 code | 20 blank | 7 comment | 40 complexity | 268edfaed10ee5a51e31131a6b33c682 MD5 | raw file
  1<cfcomponent output="false">
  2	<cfinclude template="../../global/cfml.cfm">
  3
  4	<cffunction name="init" access="public" returntype="any" output="false">
  5		<cfargument name="datasource" type="string" required="true">
  6		<cfargument name="username" type="string" required="true">
  7		<cfargument name="password" type="string" required="true">
  8		<cfset variables.instance.connection = arguments>
  9		<cfreturn this>
 10	</cffunction>
 11
 12	<cffunction name="$tableName" returntype="string" access="public" output="false">
 13		<cfargument name="list" type="string" required="true">
 14		<cfargument name="action" type="string" required="true">
 15		<cfscript>
 16			var loc = {};
 17			loc.returnValue = "";
 18			loc.iEnd = ListLen(arguments.list);
 19			for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
 20			{
 21				loc.iItem = ListGetAt(arguments.list, loc.i);
 22				if (arguments.action == "remove")
 23					loc.iItem = ListRest(loc.iItem, "."); // removes table names
 24				loc.returnValue = ListAppend(loc.returnValue, loc.iItem);
 25			}
 26		</cfscript>
 27		<cfreturn loc.returnValue>
 28	</cffunction>
 29
 30	<cffunction name="$columnAlias" returntype="string" access="public" output="false">
 31		<cfargument name="list" type="string" required="true">
 32		<cfargument name="action" type="string" required="true">
 33		<cfscript>
 34			var loc = {};
 35			loc.returnValue = "";
 36			loc.iEnd = ListLen(arguments.list);
 37			for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
 38			{
 39				loc.iItem = ListGetAt(arguments.list, loc.i);
 40				if (Find(" AS ", loc.iItem))
 41				{
 42					loc.sort = "";
 43					if (Right(loc.iItem, 4) == " ASC" || Right(loc.iItem, 5) == " DESC")
 44					{
 45						loc.sort = " " & Reverse(SpanExcluding(Reverse(loc.iItem), " "));
 46						loc.iItem = Mid(loc.iItem, 1, Len(loc.iItem)-Len(loc.sort));
 47					}
 48					loc.alias = Reverse(SpanExcluding(Reverse(loc.iItem), " "));
 49					if (arguments.action == "keep")
 50							loc.iItem = loc.alias; // keeps the alias only
 51					else if (arguments.action == "remove")
 52						loc.iItem = Replace(loc.iItem, " AS " & loc.alias, ""); // removes the alias
 53					loc.iItem = loc.iItem & loc.sort;
 54				}
 55				loc.returnValue = ListAppend(loc.returnValue, loc.iItem);
 56			}
 57		</cfscript>
 58		<cfreturn loc.returnValue>
 59	</cffunction>
 60
 61	<cffunction name="$removeColumnAliasesInOrderClause" returntype="array" access="public" output="false">
 62		<cfargument name="sql" type="array" required="true">
 63		<cfscript>
 64			var loc = {};
 65			loc.returnValue = arguments.sql;
 66			if (IsSimpleValue(loc.returnValue[ArrayLen(loc.returnValue)]) && Left(loc.returnValue[ArrayLen(loc.returnValue)], 9) == "ORDER BY ")
 67			{
 68				// remove the column aliases from the order by clause (this is passed in so that we can handle sub queries with calculated properties)
 69				loc.pos = ArrayLen(loc.returnValue);
 70				loc.orderByClause = ReplaceNoCase(loc.returnValue[loc.pos], "ORDER BY ", "");
 71				loc.returnValue[loc.pos] = "ORDER BY " & $columnAlias(list=loc.orderByClause, action="remove");
 72			}
 73		</cfscript>
 74		<cfreturn loc.returnValue>
 75	</cffunction>
 76
 77	<cffunction name="$addColumnsToSelectAndGroupBy" returntype="array" access="public" output="false">
 78		<cfargument name="sql" type="array" required="true">
 79		<cfscript>
 80			var loc = {};
 81			loc.returnValue = arguments.sql;
 82			if (IsSimpleValue(loc.returnValue[ArrayLen(loc.returnValue)]) && Left(loc.returnValue[ArrayLen(loc.returnValue)], 8) IS "ORDER BY" && IsSimpleValue(loc.returnValue[ArrayLen(loc.returnValue)-1]) && Left(loc.returnValue[ArrayLen(loc.returnValue)-1], 8) IS "GROUP BY")
 83			{
 84				loc.iEnd = ListLen(loc.returnValue[ArrayLen(loc.returnValue)]);
 85				for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
 86				{
 87					loc.item = Trim(ReplaceNoCase(ReplaceNoCase(ReplaceNoCase(ListGetAt(loc.returnValue[ArrayLen(loc.returnValue)], loc.i), "ORDER BY ", ""), " ASC", ""), " DESC", ""));
 88					if (!ListFindNoCase(ReplaceNoCase(loc.returnValue[ArrayLen(loc.returnValue)-1], "GROUP BY ", ""), loc.item))
 89						loc.returnValue[ArrayLen(loc.returnValue)-1] = ListAppend(loc.returnValue[ArrayLen(loc.returnValue)-1], loc.item);
 90					if (!ListFindNoCase(ReplaceNoCase(loc.returnValue[1], "SELECT ", ""), loc.item))
 91						loc.returnValue[1] = ListAppend(loc.returnValue[1], loc.item);
 92				}
 93			}
 94		</cfscript>
 95		<cfreturn loc.returnValue>
 96	</cffunction>
 97
 98	<cffunction name="$getColumns" returntype="query" access="public" output="false" hint="retrieves all the column information from a table">
 99		<cfargument name="tableName" type="string" required="true" hint="the table to retrieve column information for">
100		<cfscript>
101			var loc = {};
102			loc.args = duplicate(variables.instance.connection);
103			loc.args.table = arguments.tableName;
104			if (application.wheels.showErrorInformation)
105			{
106				try
107				{
108					loc.columns = $getColumnInfo(argumentCollection=loc.args);
109				}
110				catch (Any e)
111				{
112					$throw(type="Wheels.TableNotFound", message="The `#arguments.tableName#` table could not be found in the database.", extendedInfo="Add a table named `#arguments.tableName#` to your database or tell Wheels to use a different table for this model. For example you can tell a `user` model to use a table called `tbl_users` by creating a `User.cfc` file in the `models` folder, creating an `init` method inside it and then calling `table(""tbl_users"")` from within it.");
113				}
114			}
115			else
116			{
117				loc.columns = $getColumnInfo(argumentCollection=loc.args);
118			}
119		</cfscript>
120		<cfreturn loc.columns>
121	</cffunction>
122
123	<cffunction name="$getValidationType" returntype="string" access="public" output="false">
124		<cfargument name="type" type="string" required="true">
125		<cfswitch expression="#arguments.type#">
126			<cfcase value="cf_sql_real,cf_sql_numeric,cf_sql_float,cf_sql_decimal,cf_sql_double" delimiters=",">
127				<cfreturn "float">
128			</cfcase>
129			<cfcase value="cf_sql_tinyint,cf_sql_smallint,cf_sql_integer,cf_sql_bigint" delimiters=",">
130				<cfreturn "integer">
131			</cfcase>
132			<cfcase value="cf_sql_char,cf_sql_varchar" delimiters=",">
133				<cfreturn "string">
134			</cfcase>
135			<cfcase value="cf_sql_date,cf_sql_timestamp,cf_sql_time" delimiters=",">
136				<cfreturn "datetime">
137			</cfcase>
138			<cfdefaultcase>
139				<cfreturn "">
140			</cfdefaultcase>
141		</cfswitch>
142	</cffunction>
143
144	<cffunction name="$cleanInStatmentValue" returntype="string" access="public" output="false">
145		<cfargument name="statement" type="string" required="true">
146		<cfscript>
147		var loc = {};
148		loc.delim = ",";
149		if (Find("'", arguments.statement))
150		{
151			loc.delim = "','";
152			arguments.statement = RemoveChars(arguments.statement, 1, 1);
153			arguments.statement = reverse(RemoveChars(reverse(arguments.statement), 1, 1));
154			arguments.statement = Replace(arguments.statement, "''", "'", "all");
155		}
156		arguments.statement = ReplaceNoCase(arguments.statement, loc.delim, chr(7), "all");
157		</cfscript>
158		<cfreturn arguments.statement>
159	</cffunction>
160
161	<cffunction name="$CFQueryParameters" returntype="struct" access="public" output="false">
162		<cfargument name="settings" type="struct" required="true">
163		<cfscript>
164		var loc = {};
165		loc.params = {};
166		loc.params.cfsqltype = arguments.settings.type;
167		loc.params.value = arguments.settings.value;
168		if (StructKeyExists(arguments.settings, "null"))
169		{
170			loc.params.null = arguments.settings.null;
171		}
172		if (StructKeyExists(arguments.settings, "scale") AND arguments.settings.scale GT 0)
173		{
174			loc.params.scale = arguments.settings.scale;
175		}
176		if (StructKeyExists(arguments.settings, "list") AND arguments.settings.list)
177		{
178			loc.params.list = arguments.settings.list;
179			loc.params.separator = chr(7);
180			loc.params.value = $cleanInStatmentValue(loc.params.value);
181		}
182		if (!IsBinary(loc.params.value) && loc.params.value eq "null")
183		{
184			loc.params.useNull = true;
185		}
186		</cfscript>
187		<cfreturn loc.params>
188	</cffunction>
189
190	<cffunction name="$performQuery" returntype="struct" access="public" output="false">
191		<cfargument name="sql" type="array" required="true">
192		<cfargument name="parameterize" type="boolean" required="true">
193		<cfargument name="limit" type="numeric" required="false" default="0">
194		<cfargument name="offset" type="numeric" required="false" default="0">
195		<cfargument name="connection" type="struct" required="false" default="#variables.instance.connection#">
196		<cfargument name="$primaryKey" type="string" required="false" default="">
197		<cfscript>
198		var loc = {};
199		var query = {};
200
201		loc.returnValue = {};
202		loc.args = duplicate(arguments.connection);
203		loc.args.result = "loc.result";
204		loc.args.name = "query.name";
205		if (StructKeyExists(loc.args, "username") && !Len(loc.args.username))
206		{
207			StructDelete(loc.args, "username", false);
208		}
209		if (StructKeyExists(loc.args, "password") && !Len(loc.args.password))
210		{
211			StructDelete(loc.args, "password", false);
212		}
213		// set queries in Railo to not preserve single quotes on the entire
214		// cfquery block (we'll handle this individually in the SQL statement instead)
215		if (application.wheels.serverName == "Railo")
216			loc.args.psq = false;
217
218		// overloaded arguments are settings for the query
219		loc.orgArgs = duplicate(arguments);
220		StructDelete(loc.orgArgs, "sql", false);
221		StructDelete(loc.orgArgs, "parameterize", false);
222		StructDelete(loc.orgArgs, "limit", false);
223		StructDelete(loc.orgArgs, "offset", false);
224		StructDelete(loc.orgArgs, "$primaryKey", false);
225		StructAppend(loc.args, loc.orgArgs, true);
226		</cfscript>
227
228		<cfquery attributeCollection="#loc.args#"><cfloop array="#arguments.sql#" index="loc.i"><cfif IsStruct(loc.i)><cfset loc.queryParamAttributes = $CFQueryParameters(loc.i)><cfif StructKeyExists(loc.queryParamAttributes, "useNull")>NULL<cfelseif StructKeyExists(loc.queryParamAttributes, "list")><cfif arguments.parameterize>(<cfqueryparam attributeCollection="#loc.queryParamAttributes#">)<cfelse>(#PreserveSingleQuotes(loc.i.value)#)</cfif><cfelse><cfif arguments.parameterize><cfqueryparam attributeCollection="#loc.queryParamAttributes#"><cfelse>#$quoteValue(loc.i.value)#</cfif></cfif><cfelse><cfset loc.i = Replace(PreserveSingleQuotes(loc.i), "[[comma]]", ",", "all")>#PreserveSingleQuotes(loc.i)#</cfif>#chr(13)##chr(10)#</cfloop><cfif arguments.limit>LIMIT #arguments.limit#<cfif arguments.offset>#chr(13)##chr(10)#OFFSET #arguments.offset#</cfif></cfif></cfquery>
229
230		<cfscript>
231		if (StructKeyExists(query, "name"))
232			loc.returnValue.query = query.name;
233
234		// get/set the primary key value if necessary
235		// will be done on insert statement involving auto-incremented primary keys when Railo/ACF cannot retrieve it for us
236		// this happens on non-supported databases (example: H2) and drivers (example: jTDS)
237		loc.$id = $identitySelect(queryAttributes=loc.args, result=loc.result, primaryKey=arguments.$primaryKey);
238		if (StructKeyExists(loc, "$id"))
239			StructAppend(loc.result, loc.$id);
240
241		loc.returnValue.result = loc.result;
242		</cfscript>
243		<cfreturn loc.returnValue>
244	</cffunction>
245
246	<cffunction name="$getColumnInfo" returntype="query" access="public" output="false">
247		<cfargument name="table" type="string" required="true">
248		<cfargument name="datasource" type="string" required="true">
249		<cfargument name="username" type="string" required="true">
250		<cfargument name="password" type="string" required="true">
251		<cfset arguments.type = "columns">
252		<cfreturn $dbinfo(argumentCollection=arguments)>
253	</cffunction>
254
255	<cffunction name="$quoteValue" returntype="string" access="public" output="false">
256		<cfargument name="str" type="string" required="true" hint="string to quote">
257		<cfscript>
258		if (!IsNumeric(arguments.str))
259		{
260			arguments.str = "'#arguments.str#'";
261		}
262		return arguments.str;
263		</cfscript>
264	</cffunction>
265
266	<cffunction name="$tableAliasForJoin" returntype="string" access="public" output="false">
267		<cfargument name="table" type="string" required="true">
268		<cfargument name="alias" type="string" required="true">
269		<cfreturn "#arguments.table# AS #arguments.alias#">
270	</cffunction>
271
272	<cfinclude template="../../plugins/injection.cfm">
273</cfcomponent>