<cfcomponent displayname="SampleGateway" hint="I am a sample CFC that implements the Data Gateway pattern." output="false">

	<cfset variables.instance = StructNew() />
	<cfset variables.instance.datasource = "" />

<!---------------------------------------------------------------------------->	
<!--- Constructor --->		
	<cffunction name="init" access="public" output="false" returntype="SampleGateway">
		<cfargument name="datasource" type="string" required="true" />
		<cfset setDatasource(arguments.datasource) />
		<cfreturn this />	
	</cffunction>
	
<!---------------------------------------------------------------------------->	
<!--- Accessor Methods --->
	<cffunction name="getDatasource" access="public" output="false" returntype="string">
		<cfreturn variables.instance.datasource />
	</cffunction>
	
	<cffunction name="setDatasource" access="public" output="false" returntype="VOID">
		<cfargument name="datasource" type="string" required="true" /> 
		<cfset variables.instance.datasource = arguments.datasource />
	</cffunction>

<!---------------------------------------------------------------------------->	
<!--- Query Methods --->
	<cffunction name="getAllCustomers" access="public" output="false" returntype="query">
		<cfset var customerQry = "" />
		<cfquery name="customerQry" datasource="#getDatasource()#">
			SELECT 
				customer.id,
				customer.firstName,
				customer.lastName,
				customer.loginName,
				customer.isActive
			FROM customer
			ORDER BY
				customer.lastName, customer.firstName
		</cfquery>
		
		<cfreturn customerQry />
	</cffunction>

	<cffunction name="getActiveCustomers" access="public" output="false" returntype="query">
		<cfset var customerQry = "" />
		<cfquery name="customerQry" datasource="#getDatasource()#">
			SELECT 
				customer.id,
				customer.firstName,
				customer.lastName,
				customer.loginName,
				customer.isActive
			FROM customer
			WHERE customer.isActive = 1
			ORDER BY
				customer.lastName, customer.firstName
		</cfquery>
		
		<cfreturn customerQry />
	</cffunction>

	<cffunction name="getCustomersByAddress" access="public" output="false" returntype="query">
		<cfargument name="city" type="string" required="false" />
		<cfargument name="state" type="string" required="false" />
		<cfargument name="zip" type="numeric" required="false" />

		<cfset var customerQry = "" />
		<cfquery name="customerQry" datasource="#getDatasource()#">
			SELECT 
				customer.id,
				customer.firstName,
				customer.lastName,
				customer.loginName,
				customer.isActive,
				address.streetAddress1,
				address.streetAddress2,
				address.city,
				address.state,
				address.zip
			FROM customer
				INNER JOIN address
					ON customer.id = address.customerID
			WHERE
				1=1
				<cfif structKeyExists(arguments, "city")>
					AND address.city = <cfqueryparam value="#arguments.city#" cfsqltype="cf_sql_varchar" />
				</cfif>
				<cfif structKeyExists(arguments, "state")>
					AND address.state = <cfqueryparam value="#arguments.state#" cfsqltype="cf_sql_varchar" />
				</cfif>
				<cfif structKeyExists(arguments, "zip")>
					AND address.zip = <cfqueryparam value="#arguments.zip#" cfsqltype="cf_sql_integer" />
				</cfif>
			ORDER BY
				customer.lastName, customer.firstName
		</cfquery>
		
		<cfreturn customerQry />
	</cffunction>
	
	<cffunction name="searchCustomers" access="public" output="false" returntype="query">
		<cfargument name="firstName" type="string" required="false" default="" />
		<cfargument name="lastName" type="string" required="false" default="" />
		<cfargument name="loginName" type="string" required="false" default="" />
		<cfargument name="isActive" type="boolean" required="false" />
		<cfargument name="city" type="string" required="false" />
		<cfargument name="state" type="string" required="false" />
		<cfargument name="zip" type="numeric" required="false" />
		<cfargument name="orderByColumn" type="numeric" required="false" />

		<cfset var customerQry = "" />
		<cfquery name="customerQry" datasource="#getDatasource()#">
			SELECT 
				customer.id,
				customer.firstName,
				customer.lastName,
				customer.loginName,
				customer.isActive,
				address.streetAddress1,
				address.streetAddress2,
				address.city,
				address.state,
				address.zip
			FROM customer
				LEFT OUTER JOIN address
					ON customer.id = address.customerID
			WHERE
				1=1
				<cfif structKeyExists(arguments, "firstName")>
					AND customer.firstName LIKE '#arguments.firstName#%'
				</cfif>
				<cfif structKeyExists(arguments, "lastName")>
					AND customer.firstName LIKE '#arguments.lastName#%'
				</cfif>
				<cfif structKeyExists(arguments, "loginName")>
					AND customer.firstName = <cfqueryparam value="#arguments.loginName#" cfsqltype="cf_sql_varchar" />
				</cfif>
				<cfif structKeyExists(arguments, "isActive")>
					AND customer.isActive = <cfqueryparam value="#iif(arguments.isActive, DE("1"), DE("0"))#" cfsqltype="cf_sql_integer" />
				</cfif>
				<cfif structKeyExists(arguments, "city")>
					AND address.city = <cfqueryparam value="#arguments.city#" cfsqltype="cf_sql_varchar" />
				</cfif>
				<cfif structKeyExists(arguments, "state")>
					AND address.state = <cfqueryparam value="#arguments.state#" cfsqltype="cf_sql_varchar" />
				</cfif>
				<cfif structKeyExists(arguments, "zip")>
					AND address.zip = <cfqueryparam value="#arguments.zip#" cfsqltype="cf_sql_integer" />
				</cfif>
			ORDER BY
				<cfif structKeyExists(arguments, "orderByColumn")>
					#arguments.orderByColumn#
				<cfelse>
					customer.lastName, customer.firstName
				</cfif>
		</cfquery>
		
		<cfreturn customerQry />
	</cffunction>
</cfcomponent>