PageRenderTime 26ms CodeModel.GetById 18ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/wheels/model/serialize.cfm

http://cfwheels.googlecode.com/
ColdFusion | 176 lines | 160 code | 16 blank | 0 comment | 34 complexity | c54d3a718509f8cf77365f40531fe202 MD5 | raw file
  1<cffunction name="$serializeQueryToObjects" access="public" output="false" returntype="any">
  2	<cfargument name="query" type="query" required="true" />
  3	<cfargument name="include" type="string" required="false" default="" />
  4	<cfargument name="callbacks" type="string" required="false" default="true" />
  5	<cfargument name="returnIncluded" type="string" required="false" default="true" />
  6	<cfscript>
  7		var loc = {};
  8		// grab our objects as structs first so we don't waste cpu creating objects we don't need
  9		loc.returnValue = $serializeQueryToStructs(argumentCollection=arguments);	
 10	</cfscript>
 11	<cfreturn $serializeStructsToObjects(structs=loc.returnValue, argumentCollection=arguments) />
 12</cffunction>
 13
 14<cffunction name="$serializeStructsToObjects" access="public" output="false" returntype="any">
 15	<cfargument name="structs" type="any" required="true" />
 16	<cfargument name="include" type="string" required="true" />
 17	<cfargument name="callbacks" type="string" required="true" />
 18	<cfargument name="returnIncluded" type="string" required="true" />
 19	<cfscript>
 20		var loc = {};
 21		
 22		if (IsStruct(arguments.structs))
 23			loc.returnValue = [ arguments.structs ];
 24		else if (IsArray(arguments.structs))
 25			loc.returnValue = arguments.structs;
 26		
 27		loc.iEnd = ArrayLen(loc.returnValue);
 28		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
 29		{
 30		
 31			if (Len(arguments.include) && arguments.returnIncluded)
 32			{
 33				// create each object from the assocations before creating our root object
 34				loc.xEnd = ListLen(arguments.include);
 35				for (loc.x = 1; loc.x lte loc.xEnd; loc.x++)
 36				{
 37					loc.include = ListGetAt(arguments.include, loc.x);
 38					loc.model = model(variables.wheels.class.associations[loc.include].modelName);
 39					if (variables.wheels.class.associations[loc.include].type == "hasMany")
 40					{
 41						loc.jEnd = ArrayLen(loc.returnValue[loc.i][loc.include]);
 42						for (loc.j=1; loc.j <= loc.jEnd; loc.j++)
 43							loc.returnValue[loc.i][loc.include][loc.j] = loc.model.$createInstance(properties=loc.returnValue[loc.i][loc.include][loc.j], persisted=true, base=false, callbacks=arguments.callbacks);
 44					}
 45					else
 46					{
 47						// we have a hasOne or belongsTo assocation, so just add the object to the root object
 48						loc.returnValue[loc.i][loc.include] = loc.model.$createInstance(properties=loc.returnValue[loc.i][loc.include], persisted=true, base=false, callbacks=arguments.callbacks);
 49					}
 50				}
 51			}
 52		
 53			// create an instance
 54			loc.returnValue[loc.i] = $createInstance(properties=loc.returnValue[loc.i], persisted=true, callbacks=arguments.callbacks);
 55		}
 56	</cfscript>
 57	<cfreturn loc.returnValue />
 58</cffunction>
 59
 60<cffunction name="$serializeQueryToStructs" access="public" output="false" returntype="any">
 61	<cfargument name="query" type="query" required="true" />
 62	<cfargument name="include" type="string" required="true" />
 63	<cfargument name="callbacks" type="string" required="true" />
 64	<cfargument name="returnIncluded" type="string" required="true" />
 65	<cfscript>
 66		var loc = {};
 67		loc.returnValue = [];
 68		loc.doneStructs = "";
 69		
 70		// loop through all of our records and create an object for each row in the query
 71		for (loc.i=1; loc.i <= arguments.query.recordCount; loc.i++)
 72		{
 73			// create a new struct
 74			loc.struct = $queryRowToStruct(properties=arguments.query, row=loc.i);
 75			loc.structHash = $hashedKey(loc.struct);
 76			if (!ListFind(loc.doneStructs, loc.structHash, Chr(7)))
 77			{
 78				if (Len(arguments.include) && arguments.returnIncluded)
 79				{
 80					// loop through our assocations to build nested objects attached to the main object
 81					loc.xEnd = ListLen(arguments.include);
 82					for (loc.x = 1; loc.x lte loc.xEnd; loc.x++)
 83					{
 84						loc.include = ListGetAt(arguments.include, loc.x);
 85						if (variables.wheels.class.associations[loc.include].type == "hasMany")
 86						{
 87							// we have a hasMany assocation, so loop through all of the records again to find the ones that belong to our root object
 88							loc.struct[loc.include] = [];
 89							loc.hasManyDoneStructs = "";
 90							
 91							// only get a reference to our model once per assocation
 92							loc.model = model(variables.wheels.class.associations[loc.include].modelName); 
 93							
 94							for (loc.j=1; loc.j <= arguments.query.recordCount; loc.j++)
 95							{
 96								// is there anything we can do here to not instantiate an object if it is not going to be use or is already created
 97								// this extra instantiation is really slowing things down
 98								loc.hasManyStruct = loc.model.$queryRowToStruct(properties=arguments.query, row=loc.j, base=false);
 99								loc.hasManyStructHash = $hashedKey(loc.hasManyStruct);
100								
101								if (!ListFind(loc.hasManyDoneStructs, loc.hasManyStructHash, Chr(7)))
102								{
103									// create object instance from values in current query row if it belongs to the current object
104									loc.primaryKeyColumnValues = "";
105									loc.kEnd = ListLen(primaryKeys());
106									
107									for (loc.k=1; loc.k <= loc.kEnd; loc.k++)
108										loc.primaryKeyColumnValues = ListAppend(loc.primaryKeyColumnValues, arguments.query[primaryKeys(loc.k)][loc.j]);
109
110									if (Len(loc.model.$keyFromStruct(loc.hasManyStruct)) && this.$keyFromStruct(loc.struct) == loc.primaryKeyColumnValues)
111										ArrayAppend(loc.struct[loc.include], loc.hasManyStruct);
112									
113									loc.hasManyDoneStructs = ListAppend(loc.hasManyDoneStructs, loc.hasManyStructHash, Chr(7));
114								}
115							}
116						}
117						else
118						{
119							// we have a hasOne or belongsTo assocation, so just add the object to the root object
120							loc.struct[loc.include] = model(variables.wheels.class.associations[loc.include].modelName).$queryRowToStruct(properties=arguments.query, row=loc.i, base=false);
121						}
122					}
123				}
124				ArrayAppend(loc.returnValue, loc.struct);
125				loc.doneStructs = ListAppend(loc.doneStructs, loc.structHash, Chr(7));
126			}
127		}
128	</cfscript>
129	<cfreturn loc.returnValue />
130</cffunction>
131
132<cffunction name="$queryRowToStruct" access="public" output="false" returntype="struct">
133	<cfargument name="properties" type="any" required="true">
134	<cfargument name="name" type="string" required="false" default="#variables.wheels.class.modelName#">
135	<cfargument name="row" type="numeric" required="false" default="1">
136	<cfargument name="base" type="boolean" required="false" default="true">
137	<cfscript>
138		var loc = {};
139		loc.returnValue = {};
140		
141		loc.allProperties = ListAppend(variables.wheels.class.propertyList, variables.wheels.class.calculatedPropertyList);
142		loc.iEnd = ListLen(loc.allProperties);
143		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
144		{
145			try // coldfusion has a problem with empty strings in queries for bit types
146			{
147				loc.iItem = ListGetAt(loc.allProperties, loc.i);
148				if (!arguments.base && ListFindNoCase(arguments.properties.columnList, arguments.name & loc.iItem))
149					loc.returnValue[loc.iItem] = arguments.properties[arguments.name & loc.iItem][arguments.row];
150				else if (ListFindNoCase(arguments.properties.columnList, loc.iItem))
151					loc.returnValue[loc.iItem] = arguments.properties[loc.iItem][arguments.row];
152			}
153			catch (Any e)
154			{
155				loc.returnValue[loc.iItem] = "";
156			}
157		}	
158	</cfscript>
159	<cfreturn loc.returnValue />
160</cffunction>
161
162<cffunction name="$keyFromStruct" access="public" output="false" returntype="string">
163	<cfargument name="struct" type="struct" required="true">
164	<cfscript>
165		var loc = {};
166		loc.returnValue = "";
167		loc.iEnd = ListLen(primaryKeys());
168		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
169		{
170			loc.property = primaryKeys(loc.i);
171			if (StructKeyExists(arguments.struct, loc.property))
172				loc.returnValue = ListAppend(loc.returnValue, arguments.struct[loc.property]);
173		}
174		</cfscript>
175	<cfreturn loc.returnValue>
176</cffunction>