initial
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<cfcomponent extends="taffy.core.api">
|
||||
<cfscript>
|
||||
|
||||
this.name = "rate_limiting_example";
|
||||
|
||||
function onApplicationStart(){
|
||||
application.accessLog = queryNew('apiKey,accessTime','varchar,time');
|
||||
application.accessLimit = 100; //requests
|
||||
application.accessPeriod = 60; //seconds
|
||||
|
||||
return super.onApplicationStart();
|
||||
}
|
||||
|
||||
function onTaffyRequest(verb, cfc, requestArguments, mimeExt){
|
||||
var usage = 0;
|
||||
|
||||
//require some api key
|
||||
if (!structKeyExists(requestArguments, "apiKey")){
|
||||
return noData().withStatus(401, "API Key Required");
|
||||
}
|
||||
|
||||
//check usage
|
||||
usage = getAccessRate(requestArguments.apiKey);
|
||||
if (usage lte application.accessLimit){
|
||||
logAccess(requestArguments.apiKey);
|
||||
return true;
|
||||
}else{
|
||||
return noData().withStatus(420, "Enhance your calm");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
</cfscript>
|
||||
|
||||
<cffunction name="getAccessRate" access="private" output="false">
|
||||
<cfargument name="apiKey" required="true" />
|
||||
<cfset var local = structNew() />
|
||||
<!--- now get matches for the current api key --->
|
||||
<cfquery name="local.accessLookup" dbtype="query">
|
||||
select accessTime
|
||||
from application.accessLog
|
||||
where apiKey = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.apiKey#" />
|
||||
and accessTime > <cfqueryparam cfsqltype="cf_sql_timestamp" value="#dateAdd("s",(-1 * application.accessPeriod),now())#" />
|
||||
</cfquery>
|
||||
<!--- if access log is getting long, do some cleanup --->
|
||||
<cfif local.accessLookup.recordCount gt application.accessLimit>
|
||||
<cfset pruneAccessLog() />
|
||||
</cfif>
|
||||
<cfreturn local.accessLookup.recordCount />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="logAccess" access="private" output="true">
|
||||
<cfargument name="apiKey" required="true" type="string" />
|
||||
<cfset var qLog = '' />
|
||||
<cflock timeout="10" type="readonly" name="logging">
|
||||
<cfset queryAddRow(application.accessLog)/>
|
||||
<cfset querySetCell(application.accessLog, "accessTime", now()) />
|
||||
<cfset querySetCell(application.accessLog, "apiKey", arguments.apiKey) />
|
||||
</cflock>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="pruneAccessLog" access="private" output="false">
|
||||
<cflock timeout="10" type="readonly" name="logging">
|
||||
<cfquery name="application.accessLog" dbtype="query">
|
||||
delete
|
||||
from application.accessLog
|
||||
where accessTime < <cfqueryparam cfsqltype="cf_sql_timestamp" value="#dateAdd("s",(-1 * application.accessPeriod),now())#" />
|
||||
</cfquery>
|
||||
</cflock>
|
||||
</cffunction>
|
||||
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,6 @@
|
||||
<!---
|
||||
DO NOT DELETE THIS FILE
|
||||
===============================
|
||||
This file is necessary for Taffy to work, but should be blank.
|
||||
All requests funnel through it, but are handled by framework internal functionality.
|
||||
--->
|
||||
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="2.1">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Over Rate Limit" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="My Users" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<intProp name="LoopController.loops">-1</intProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">30</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">13</stringProp>
|
||||
<longProp name="ThreadGroup.start_time">1300766515000</longProp>
|
||||
<longProp name="ThreadGroup.end_time">1300766515000</longProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
|
||||
<stringProp name="ConstantTimer.delay">1000</stringProp>
|
||||
</ConstantTimer>
|
||||
<hashTree/>
|
||||
<HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="HTTP Request" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">80</stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout">1000</stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout">5000</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/taffy/examples/api_rateLimited/index.cfm/artist/1?apikey=fdsa</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<boolProp name="HTTPSampler.monitor">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
</HTTPSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>true</xml>
|
||||
<fieldNames>false</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="GraphVisualizer" testclass="ResultCollector" testname="Graph Results" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>true</xml>
|
||||
<fieldNames>false</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>true</xml>
|
||||
<fieldNames>false</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
||||
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="2.1">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Within Rate Limit" enabled="true">
|
||||
<stringProp name="TestPlan.comments"></stringProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="My Users" enabled="true">
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<intProp name="LoopController.loops">-1</intProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">1</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">20</stringProp>
|
||||
<longProp name="ThreadGroup.start_time">1300766515000</longProp>
|
||||
<longProp name="ThreadGroup.end_time">1300766515000</longProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
|
||||
<stringProp name="ConstantTimer.delay">1100</stringProp>
|
||||
</ConstantTimer>
|
||||
<hashTree/>
|
||||
<HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="HTTP Request" enabled="true">
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||
<stringProp name="HTTPSampler.port">80</stringProp>
|
||||
<stringProp name="HTTPSampler.connect_timeout">1000</stringProp>
|
||||
<stringProp name="HTTPSampler.response_timeout">5000</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||
<stringProp name="HTTPSampler.path">/taffy/examples/api_rateLimited/index.cfm/artist/1?apikey=fdsa</stringProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||
<boolProp name="HTTPSampler.monitor">false</boolProp>
|
||||
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||
</HTTPSampler>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>true</xml>
|
||||
<fieldNames>false</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="GraphVisualizer" testclass="ResultCollector" testname="Graph Results" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>true</xml>
|
||||
<fieldNames>false</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>true</xml>
|
||||
<fieldNames>false</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
||||
@@ -0,0 +1,81 @@
|
||||
<cfcomponent extends="taffy.core.resource" taffy:uri="/artist/{id}" hint="some hint about this resource">
|
||||
|
||||
<cffunction name="get" access="public" output="false">
|
||||
<cfargument name="id" type="numeric" required="true" />
|
||||
<cfset var q = ""/>
|
||||
<cfset var col = "" />
|
||||
<cfset var rtn = StructNew() />
|
||||
<cfquery name="q" datasource="cfartgallery" cachedwithin="#createTimeSpan(0,0,1,0)#">
|
||||
select * from artists where artistId = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.id#" />
|
||||
</cfquery>
|
||||
<cfif q.recordCount gt 0>
|
||||
<cfloop list="#q.ColumnList#" index="col">
|
||||
<cfset rtn[col] = q[col][1] />
|
||||
</cfloop>
|
||||
<cfreturn representationOf(rtn).withStatus(200) />
|
||||
<cfelse>
|
||||
<cfreturn noData().withStatus(404) />
|
||||
</cfif>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="put" access="public" output="false">
|
||||
<cfargument name="id" type="numeric" required="true" />
|
||||
<cfargument name="firstname" type="string" required="false" default="" />
|
||||
<cfargument name="lastname" type="string" required="false" default="" />
|
||||
<cfargument name="address" type="string" required="false" default="" hint="some hint about this parameter" />
|
||||
<cfargument name="city" type="string" required="false" default="" />
|
||||
<cfargument name="state" type="string" required="false" default="" />
|
||||
<cfargument name="postalcode" type="string" required="false" default="" />
|
||||
<cfargument name="email" type="string" required="false" default="" />
|
||||
<cfargument name="phone" type="string" required="false" default="" />
|
||||
<cfargument name="fax" type="string" required="false" default="" />
|
||||
<cfargument name="thepassword" type="string" required="false" default="" />
|
||||
<cfset var q = "" />
|
||||
<cfquery name="q" datasource="cfartgallery">
|
||||
update artists
|
||||
set artistid=artistid
|
||||
<cfif len(arguments.firstname)>
|
||||
,firstname = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.firstname#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.lastname)>
|
||||
,lastname = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.lastname#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.address)>
|
||||
,address = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.address#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.city)>
|
||||
,city = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.city#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.state)>
|
||||
,state = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.state#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.postalcode)>
|
||||
,postalcode = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.postalcode#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.email)>
|
||||
,email = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.email#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.phone)>
|
||||
,phone = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.phone#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.fax)>
|
||||
,fax = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.fax#" />
|
||||
</cfif>
|
||||
<cfif len(arguments.thepassword)>
|
||||
,thepassword = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.thepassword#" />
|
||||
</cfif>
|
||||
where artistid = <cfqueryparam cfsqltype="cf_sql_numeric" value="#arguments.id#" />
|
||||
</cfquery>
|
||||
<cfreturn noData().withStatus(200) />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="delete" access="public" output="false">
|
||||
<cfargument name="id" type="numeric" required="true" />
|
||||
<cfset var q = "" />
|
||||
<cfquery name="q" datasource="cfartgallery">
|
||||
delete from artists where artistid = <cfqueryparam cfsqltype="cf_sql_numeric" value="#arguments.id#" />
|
||||
</cfquery>
|
||||
<cfreturn noData().withStatus(200) />
|
||||
</cffunction>
|
||||
|
||||
</cfcomponent>
|
||||
Reference in New Issue
Block a user