├── .gitignore
├── base.cfc
├── collection.cfc
├── content.cfc
├── cookie.cfc
├── execute.cfc
├── flush.cfc
├── header.cfc
├── htmlhead.cfc
├── index.cfc
├── invoke.cfc
├── loginuser.cfc
├── logout.cfc
├── objectcache.cfc
├── query.cfc
├── queryofqueries.cfc
├── readme.md
├── registry.cfc
├── schedule.cfc
├── search.cfc
├── setting.cfc
├── spreadsheet.cfc
├── tests
├── ExecuteTest.cfc
├── LoginFrameworkTest.cfc
├── SpreadsheetTest.cfc
└── queryofqueriesTest.cfc
├── wddx.cfc
└── zip.cfc
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .project
3 |
4 | .settings/org.eclipse.core.resources.prefs
5 |
6 | settings.xml
7 |
--------------------------------------------------------------------------------
/base.cfc:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | variables.tagAttributes = '';
22 | variables.parameters = [];
23 |
24 | /**
25 | * Set the name of the service tag to be invoked
26 | * @output false
27 | */
28 | private void function setTagName(string tagName)
29 | {
30 | variables.tagName = tagName;
31 | }
32 |
33 |
34 | /**
35 | * Get the name of the service tag
36 | * @output false
37 | */
38 | private string function getTagName()
39 | {
40 | return variables.tagName;
41 | }
42 |
43 |
44 | /**
45 | * Set cfc properties. Wrapper for setAttributes()
46 | * @output false
47 | */
48 | public void function setProperties()
49 | {
50 | if(structkeyexists(arguments,"1") and isstruct(arguments["1"]))
51 | setAttributes(arguments["1"]);
52 | else
53 | setAttributes(arguments);
54 | }
55 |
56 |
57 | /**
58 | * Set service tag attributes.
59 | * @output false
60 | */
61 | public void function setAttributes()
62 | {
63 | if(!structisempty(arguments))
64 | {
65 | var temp = {};
66 | if(structkeyexists(arguments,"1") and isstruct(arguments["1"]))
67 | {
68 | //include only relevant properties
69 | for(var p in arguments["1"])
70 | {
71 | if(listcontainsnocase(variables.tagAttributes,p)){
72 | temp[p] = arguments["1"][p];
73 | }
74 | }
75 | structappend(variables,temp,"yes");
76 | }
77 | else
78 | structappend(variables,arguments,"yes");
79 | }
80 | }
81 |
82 |
83 | /**
84 | * Get cfc properties. Wrapper for getAttributes()
85 | * @output false
86 | */
87 | public struct function getProperties(string attribs="")
88 | {
89 | return getAttributes(attribs);
90 | }
91 |
92 |
93 | /**
94 | * Returns a struct with all/some of the service tag attribute values. If no attributes are specified, it returns a coldfusion with all service tag attribute values
95 | * @output false
96 | */
97 | public struct function getAttributes(string attribs="")
98 | {
99 | var attributesstruct = {};
100 | var i = 0;
101 | arguments.attribs = trim(arguments.attribs) neq "" ? trim(arguments.attribs) : variables.tagAttributes;
102 |
103 | for(i=1; i lte listlen(attribs); i++)
104 | {
105 | var attrib = trim(listgetat(attribs,i));
106 | if(structkeyexists(variables,attrib))
107 | {
108 | attributesstruct[attrib] = variables[attrib];
109 | }
110 | }
111 | return attributesstruct;
112 | }
113 |
114 |
115 | /**
116 | * Clear cfc properties. Wrapper for clearAttributes()
117 | * @output false
118 | */
119 | public void function clearProperties(string attribs="")
120 | {
121 | return clearAttributes(attribs);
122 | }
123 |
124 |
125 | /**
126 | * Removes a specific service tag attribute from CFC variables scope. Invoked by clearAttributes()
127 | * @output false
128 | */
129 | private void function clearAttribute(struct tagAttributesStruct,string tagAttribute)
130 | {
131 | if(structkeyexists(tagAttributesStruct,tagAttribute))
132 | {
133 | structdelete(tagAttributesStruct,tagAttribute);
134 | }
135 | }
136 |
137 |
138 | /**
139 | * Removes all|some of the service tag attributes from CFC variables scope. Accepts a list of service tag attributes to remove. If no attributes are specified, all attributes are
140 | * removed from CFC variables scope
141 | * @output false
142 | */
143 | public void function clearAttributes(string tagAttributesToClear="")
144 | {
145 | var attributeslist = isdefined("arguments.tagAttributesToClear") and trim(arguments.tagAttributesToClear) neq "" ? arguments.tagAttributesToClear : variables.tagAttributes;
146 | var i = 0;
147 |
148 | for(i=1;i lte listlen(attributeslist); i++)
149 | {
150 | var attrib = trim(listgetat(attributeslist,i));
151 | clearAttribute(variables,attrib);
152 | }
153 | }
154 |
155 |
156 | /**
157 | * Removes service tag attributes
158 | * @output false
159 | */
160 | public void function clear()
161 | {
162 | clearAttributes();
163 | clearParams();
164 | }
165 |
166 |
167 | /**
168 | * Resets child tags by resetting the parameters array
169 | * @output false
170 | */
171 | public void function clearParams()
172 | {
173 | if(isdefined("variables.parameters"))
174 | {
175 | variables.parameters = [];
176 | }
177 | }
178 |
179 |
180 | /**
181 | * Returns a struct with attributes set either using implicit setters | init() | setAttributes()
182 | * @output false
183 | */
184 | private struct function getTagAttributes()
185 | {
186 | var tagAttributes = structnew();
187 | var i = 0;
188 |
189 | for(i=1; i lte listlen(variables.tagAttributes); i++)
190 | {
191 | var attrib = trim(listgetat(variables.tagAttributes,i));
192 | if(structkeyexists(variables,attrib))
193 | {
194 | tagAttributes[attrib] = variables[attrib];
195 | }
196 | }
197 | return tagAttributes;
198 | }
199 |
200 | /**
201 | * Trim tag attributes
202 | * @output false
203 | */
204 | private struct function trimAttributes(struct attribs={})
205 | {
206 | var tagAttributes = {};
207 | if(!structisempty(attribs))
208 | {
209 | for(var attrib in attribs)
210 | {
211 | tagAttributes[attrib] = isSimpleValue(attribs[attrib]) ? trim(attribs[attrib]) : attribs[attrib];
212 | }
213 | }
214 | return tagAttributes;
215 | }
216 |
217 |
218 | /**
219 | * Accepts a service tag name and returns the allowed tag attributes. Uses double-checked locking
220 | * @output false
221 | */
222 | private string function getSupportedTagAttributes(string tagName)
223 | {
224 | //store all service tag attributes in Server scope for faster access.
225 | if(not isdefined("server.coldfusion.serviceTagAttributes.#tagName#"))
226 | {
227 | lock scope="server" timeout="30" throwontimeout="yes" type="exclusive"
228 | {
229 | if(not isdefined("server.coldfusion.serviceTagAttributes.#tagName#"))
230 | {
231 | var webinf = getPageContext().getServletContext().getRealPath("/WEB-INF");
232 | var sep = server.os.name contains "windows"? "\" : "/";
233 | var cftldpath = webinf & sep & "cftags" & sep & "META-INF" & sep & "taglib.cftld";
234 | var xpath = "/taglib/tag[name='#lcase(Right(tagName,len(tagName)-2))#']/attribute/name";
235 | var cftagsXml = XmlParse(FileRead(cftldpath));
236 | var tagAttributes = xmlsearch(cftagsXml,xpath);
237 | var attributeslist = "";
238 | var i = 0;
239 | for(i=1;i lte arraylen(tagAttributes); i++)
240 | {
241 | attributeslist = listappend(attributeslist,trim(tagAttributes[i].xmltext));
242 | }
243 | server.coldfusion.serviceTagAttributes[tagName] = listsort(attributeslist,"textnocase","ASC");
244 | }
245 | }
246 | }
247 |
248 | //use a local variable for faster access
249 | lock scope="server" timeout="30" throwontimeout="yes" type="readonly"
250 | {
251 | var attributeslist = server.coldfusion.serviceTagAttributes[tagName];
252 | }
253 |
254 | return attributeslist;
255 | }
256 |
257 |
258 | /**
259 | * Add child tags like cfmailparam, cfmailpart etc
260 | * @output false
261 | */
262 | public void function addParam()
263 | {
264 | if(!structisempty(arguments))
265 | {
266 | if(isdefined("variables.parameters"))
267 | {
268 | arrayappend(variables.parameters, arguments);
269 | }
270 | }
271 | }
272 |
273 |
274 | /**
275 | * Get array of parameters added using addParam()
276 | * @output false
277 | */
278 | public array function getParameters()
279 | {
280 | return variables.parameters;
281 | }
282 |
283 |
284 | /**
285 | * Validate against any incorrect attributes passed to the child tags. This is done by passing allowExtraAttributes=false
286 | * @output false
287 | */
288 | private array function appendAllowExtraAttributes(array params)
289 | {
290 | var temp = [];
291 | var nbrOfParams = arraylen(arguments.params);
292 | var i = 0;
293 |
294 | for(i=1; i lte nbrOfParams; i++)
295 | {
296 | var param = arguments.params[i];
297 | if(isstruct(param))
298 | {
299 | structappend(param,{allowExtraAttributes=false});
300 | arrayappend(temp,param);
301 | }
302 | }
303 | return temp;
304 | }
305 |
306 |
307 |
308 |
309 |
310 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 | #mailbody#
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 | #trim(mailpartbody)#
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 | #PreserveSingleQuotes(sqlQuery)#
459 |
460 | #getPreserveSingleQuotes(sqlArray[1])#
461 |
462 |
463 |
464 |
465 |
466 | #getPreserveSingleQuotes(sqlArray[i])#
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
--------------------------------------------------------------------------------
/collection.cfc:
--------------------------------------------------------------------------------
1 | /***********************************************************************************************************
2 | *
3 | * Made by Raymond Camden, Jedi Master
4 | *
5 | * MIT License
6 | *
7 | * Copyright (c) 2011 The ColdFusion Community
8 | *
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
10 | * associated documentation files (the "Software"), to deal in the Software without restriction, including
11 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
13 | * following conditions:
14 | *
15 | * The above copyright notice and this permission notice shall be included in all copies or substantial
16 | * portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
19 | * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
20 | * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 | *
24 | * See also: http://www.opensource.org/licenses/mit-license.html
25 | *
26 | *************************************************************************************************************/
27 |
28 | /**
29 | * Collection Service to perform solr collection operations in cfscript
30 | * @name collection
31 | * @displayname ColdFusion Collection Service
32 | * @output false
33 | * @accessors true
34 | */
35 | component extends="base" {
36 |
37 | property string action;
38 | property string categories;
39 | property string collection;
40 | property string engine;
41 | property string language;
42 | property string name;
43 | property string path;
44 |
45 | property name="properties" type="any" getter="false" setter="false";
46 |
47 | //service tag to invoke
48 | variables.tagName = "CFCOLLECTION";
49 |
50 | //cfcollection tag attributes
51 | variables.tagAttributes = getSupportedTagAttributes(getTagName());
52 |
53 | /**
54 | * Default constructor invoked when search objects are created.
55 | * @return search object
56 | * @output false
57 | */
58 | public collection function init()
59 | {
60 | if(!structisempty(arguments)) structappend(variables,arguments);
61 | return this;
62 | }
63 |
64 |
65 | /**
66 | * Invoke the cfcollection service tag to get categories for a collection
67 | * Usage :: new collection().categoryList(collection="fivetag");
68 | * @output false
69 | */
70 | public struct function categoryList()
71 | {
72 | //store tag attributes to be passed to the service tag in a local variable
73 | var tagAttributes = duplicate(getTagAttributes());
74 |
75 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
76 | if (!structisempty(arguments))
77 | {
78 | structappend(tagAttributes,arguments);
79 | }
80 |
81 | tagAttributes.action="categorylist";
82 |
83 | //trim attribute values
84 | tagAttributes = trimAttributes(tagAttributes);
85 |
86 | return super.invokeTag(getTagName(),tagAttributes);
87 | }
88 |
89 | /**
90 | * Invoke the cfcollection service tag to create collections
91 | * Usage :: new collection().create(collection="fivetag",path="c...");
92 | * @output false
93 | */
94 | public struct function create()
95 | {
96 | //store tag attributes to be passed to the service tag in a local variable
97 | var tagAttributes = duplicate(getTagAttributes());
98 |
99 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
100 | if (!structisempty(arguments))
101 | {
102 | structappend(tagAttributes,arguments);
103 | }
104 |
105 | tagAttributes.action="create";
106 |
107 | //trim attribute values
108 | tagAttributes = trimAttributes(tagAttributes);
109 |
110 | return super.invokeTag(getTagName(),tagAttributes);
111 | }
112 |
113 | /**
114 | * Invoke the cfcollection service tag to delete collections
115 | * Usage :: new collection().delete(collection="boom");
116 | * @output false
117 | */
118 | public struct function delete()
119 | {
120 | //store tag attributes to be passed to the service tag in a local variable
121 | var tagAttributes = duplicate(getTagAttributes());
122 |
123 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
124 | if (!structisempty(arguments))
125 | {
126 | structappend(tagAttributes,arguments);
127 | }
128 |
129 | tagAttributes.action="delete";
130 |
131 | //trim attribute values
132 | tagAttributes = trimAttributes(tagAttributes);
133 |
134 | return super.invokeTag(getTagName(),tagAttributes);
135 | }
136 |
137 | /**
138 | * Invoke the cfcollection service tag to list solr collections in cfscript
139 | * Usage :: new collection().list();
140 | * @output false
141 | */
142 | public struct function list()
143 | {
144 | //store tag attributes to be passed to the service tag in a local variable
145 | var tagAttributes = duplicate(getTagAttributes());
146 |
147 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
148 | if (!structisempty(arguments))
149 | {
150 | structappend(tagAttributes,arguments);
151 | }
152 |
153 | tagAttributes.action="list";
154 |
155 | //trim attribute values
156 | tagAttributes = trimAttributes(tagAttributes);
157 |
158 | return super.invokeTag(getTagName(),tagAttributes);
159 | }
160 |
161 | /**
162 | * Invoke the cfcollection service tag to optimize collections
163 | * Usage :: new collection().optimize(collection="boom");
164 | * @output false
165 | */
166 | public struct function optimize()
167 | {
168 | //store tag attributes to be passed to the service tag in a local variable
169 | var tagAttributes = duplicate(getTagAttributes());
170 |
171 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
172 | if (!structisempty(arguments))
173 | {
174 | structappend(tagAttributes,arguments);
175 | }
176 |
177 | tagAttributes.action="optimize";
178 |
179 | //trim attribute values
180 | tagAttributes = trimAttributes(tagAttributes);
181 |
182 | return super.invokeTag(getTagName(),tagAttributes);
183 | }
184 |
185 |
186 | }
--------------------------------------------------------------------------------
/content.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/cookie.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/execute.cfc:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Execute Service : Executes a ColdFusion developer-specified process on a server computer.
4 | * @name execute
5 | * @displayname ColdFusion Execute(Command Line) Service
6 | * @output false
7 | * @accessors true
8 | */
9 | component extends="base"
10 | {
11 | property string name;
12 | property string arguments;
13 | property string outputFile;
14 | property numeric timeout;
15 |
16 | //service tag to invoke
17 | variables.tagName = "CFEXECUTE";
18 |
19 | //valid ldap tag attributes
20 | variables.tagAttributes = getSupportedTagAttributes(getTagName());
21 |
22 |
23 |
24 | /**
25 | * Initialization routine. Returns an instance of this component
26 | * @output false
27 | */
28 | public execute function init()
29 | {
30 | if(!structisempty(arguments))
31 | {
32 | structappend(variables,arguments,"yes");
33 | }
34 |
35 | /*
36 | Special case for cfdump:
37 | If attributes is not set in the contructor, we set it to an empty string.
38 | If this is not done, value for attributes in dump will be a struct containing all properties set in cfc variables scope.
39 | */
40 | /*
41 | if(!structkeyexists(variables,"attributes")){
42 | this.setAttributes("");
43 | }
44 | */
45 |
46 | return this;
47 | }
48 |
49 |
50 |
51 | /**
52 | * Used to set "attributes" property.
53 | * Note that implicit setter setAttributes() is not used since a method with the same name is defined in base.cfc
54 | * @output false
55 | */
56 | public void function setLdapAttributes(String attributes)
57 | {
58 | variables.attributes = attributes;
59 | }
60 |
61 |
62 |
63 | /**
64 | * Returns the "attributes" property, if defined, or an empty string
65 | * Note that implicit getter getAttributes() is not used since a method with the same name is defined in base.cfc
66 | * @output false
67 | */
68 | public function getLdapAttributes()
69 | {
70 | return structkeyexists(variables,"attributes") ? variables.attributes : "";
71 | }
72 |
73 |
74 |
75 | /**
76 | * Removes tag attributes from variables scope. Accepts a list of tag attributes
77 | * If no attributes are specified, all attributes are removed from CFC variables scope
78 | * @output false
79 | */
80 | public void function clearAttributes(string tagAttributesToClear="")
81 | {
82 | //delegate call to clearAttributes in base.cfc
83 | super.clearAttributes(tagAttributesToClear);
84 |
85 | //required since we explicitly set attributes to "" (see init method)
86 | if(!structkeyexists(variables,"attributes"))
87 | this.setAttributes("");
88 | }
89 |
90 |
91 |
92 | /**
93 | * Removes tag attributes
94 | * @output false
95 | */
96 | public void function clear()
97 | {
98 | //delegate call to clearAttributes
99 | clearAttributes();
100 | }
101 |
102 | /* ************************ BEGIN :: EXECUTE SERVICES *************************************** */
103 |
104 | /**
105 | * Invoke the cfexecute tag to provide the command line access in cfscript
106 | * @output true
107 | */
108 | public result function execute()
109 | {
110 | //store tag attributes to be passed to the service tag in a local variable
111 | var tagAttributes = duplicate(getTagAttributes());
112 |
113 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
114 | if(!structisempty(arguments))
115 | {
116 | structappend(tagAttributes,arguments,"yes");
117 | }
118 |
119 | //if a result attribute is specified, we ignore it so that we can always return the result struct
120 | if(structkeyexists(tagAttributes,"result"))
121 | {
122 | structdelete(tagAttributes, "result");
123 | }
124 |
125 | //trim attribute values
126 | tagAttributes = trimAttributes(tagAttributes);
127 |
128 | return super.invokeTag(getTagName(),tagAttributes);
129 | }
130 |
131 |
132 |
133 | /* ************************ END :: EXECUTE SERVICES *************************************** */
134 |
135 |
136 |
137 |
138 | }
--------------------------------------------------------------------------------
/flush.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/header.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/htmlhead.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/index.cfc:
--------------------------------------------------------------------------------
1 | /***********************************************************************************************************
2 | *
3 | * Made by Raymond Camden, Jedi Master
4 | *
5 | * MIT License
6 | *
7 | * Copyright (c) 2011 The ColdFusion Community
8 | *
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
10 | * associated documentation files (the "Software"), to deal in the Software without restriction, including
11 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
13 | * following conditions:
14 | *
15 | * The above copyright notice and this permission notice shall be included in all copies or substantial
16 | * portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
19 | * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
20 | * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 | *
24 | * See also: http://www.opensource.org/licenses/mit-license.html
25 | *
26 | *************************************************************************************************************/
27 |
28 | /**
29 | * Index Service to perform solr index operations in cfscript
30 | * @name index
31 | * @displayname ColdFusion Index Service
32 | * @output false
33 | * @accessors true
34 | */
35 | component extends="base" {
36 |
37 | property string action;
38 | property string collection;
39 | property string body;
40 | property string category;
41 | property string categoryTree;
42 | property string custom1;
43 | property string custom2;
44 | property string custom3;
45 | property string custom4;
46 | property string extensions;
47 | property string key;
48 | property string language;
49 | property string prefix;
50 | property string query;
51 | property string status;
52 | property string title;
53 | property string type;
54 | property string urlpath;
55 |
56 | property name="properties" type="any" getter="false" setter="false";
57 |
58 | //service tag to invoke
59 | variables.tagName = "CFINDEX";
60 |
61 | //cfcollection tag attributes
62 | variables.tagAttributes = getSupportedTagAttributes(getTagName());
63 |
64 | /**
65 | * Default constructor invoked when search objects are created.
66 | * @return search object
67 | * @output false
68 | */
69 | public index function init()
70 | {
71 | if(!structisempty(arguments)) structappend(variables,arguments);
72 | return this;
73 | }
74 |
75 | /**
76 | * Invoke the cfindex service tag to delete keys from solr collections in cfscript
77 | * Usage :: new index().delete(collection="beer",key=9);
78 | * @output false
79 | */
80 | public struct function delete()
81 | {
82 | //store tag attributes to be passed to the service tag in a local variable
83 | var tagAttributes = duplicate(getTagAttributes());
84 |
85 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
86 | if (!structisempty(arguments))
87 | {
88 | structappend(tagAttributes,arguments);
89 | }
90 |
91 | tagAttributes.action="delete";
92 |
93 | //trim attribute values
94 | tagAttributes = trimAttributes(tagAttributes);
95 |
96 | return super.invokeTag(getTagName(),tagAttributes);
97 | }
98 |
99 | /**
100 | * Invoke the cfindex service tag to purge a solr collection in cfscript
101 | * Usage :: new index().purge(collection="beer");
102 | * @output false
103 | */
104 | public struct function purge()
105 | {
106 | //store tag attributes to be passed to the service tag in a local variable
107 | var tagAttributes = duplicate(getTagAttributes());
108 |
109 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
110 | if (!structisempty(arguments))
111 | {
112 | structappend(tagAttributes,arguments);
113 | }
114 |
115 | tagAttributes.action="purge";
116 |
117 | //trim attribute values
118 | tagAttributes = trimAttributes(tagAttributes);
119 |
120 | return super.invokeTag(getTagName(),tagAttributes);
121 | }
122 |
123 | /**
124 | * Invoke the cfindex service tag to refresh solr collections in cfscript
125 | * Usage :: new index().refresh(collection="beer",query=q);
126 | * @output false
127 | */
128 | public struct function refresh()
129 | {
130 | //store tag attributes to be passed to the service tag in a local variable
131 | var tagAttributes = duplicate(getTagAttributes());
132 |
133 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
134 | if (!structisempty(arguments))
135 | {
136 | structappend(tagAttributes,arguments);
137 | }
138 |
139 | tagAttributes.action="refresh";
140 |
141 | //trim attribute values
142 | tagAttributes = trimAttributes(tagAttributes);
143 |
144 | return super.invokeTag(getTagName(),tagAttributes);
145 | }
146 |
147 | /**
148 | * Invoke the cfindex service tag to refresh solr collections in cfscript
149 | * Usage :: new index().refresh(collection="beer",query=q);
150 | * @output false
151 | */
152 | public struct function update()
153 | {
154 | //store tag attributes to be passed to the service tag in a local variable
155 | var tagAttributes = duplicate(getTagAttributes());
156 |
157 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
158 | if (!structisempty(arguments))
159 | {
160 | structappend(tagAttributes,arguments);
161 | }
162 |
163 | tagAttributes.action="update";
164 |
165 | //trim attribute values
166 | tagAttributes = trimAttributes(tagAttributes);
167 |
168 | return super.invokeTag(getTagName(),tagAttributes);
169 | }
170 |
171 | }
--------------------------------------------------------------------------------
/invoke.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/loginuser.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/logout.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/objectcache.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/query.cfc:
--------------------------------------------------------------------------------
1 | /***********************************************************************************************************
2 | *
3 | * ADOBE CONFIDENTIAL
4 | * ___________________
5 | *
6 | * Copyright 2008 Adobe Systems Incorporated
7 | * All Rights Reserved.
8 | *
9 | * NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the
10 | * terms of the Adobe license agreement accompanying it. If you have received this file from a
11 | * source other than Adobe, then your use, modification, or distribution of it requires the prior
12 | * written permission of Adobe.
13 | *************************************************************************************************************/
14 |
15 | /**
16 | * Query Service to execute SQL queries in cfscript
17 | * @name query
18 | * @displayname ColdFusion Query Service
19 | * @output false
20 | * @accessors true
21 | */
22 | component extends="base"
23 | {
24 | property string name;
25 | property numeric blockfactor;
26 | property string cachedafter;
27 | property string cachedwithin;
28 | property string dataSource;
29 | property string dbtype;
30 | property boolean debug;
31 | property numeric maxRows;
32 | property string password;
33 | property string result;
34 | property numeric timeout;
35 | property string username;
36 | property string sql;
37 |
38 | //array to store cfqueryparams
39 | variables.parameters = [];
40 |
41 | //service tag to invoke
42 | variables.tagName = "CFQUERY";
43 |
44 | //list of valid cfquery tag attributes
45 | variables.tagAttributes = getSupportedTagAttributes(getTagName());
46 |
47 | //default error message and error type
48 | variables.errorMessage = "Error Executing Database Query";
49 | variables.errorType = "Application";
50 |
51 | //constants
52 | variables.COMMA = ",";
53 | variables.RIGHTPARENTHESIS = ")";
54 | variables.NEWLINE = chr(13) & chr(10);
55 | variables.SPACE = " ";
56 | variables.EMPTYSTRING = "";
57 | variables.SINGLEQUOTE= "'";
58 | variables.NAMED_DELIMITER = ":";
59 | variables.POSITIONAL_DELIMITER = "?";
60 | variables.NAMED_DELIMITER_MARKER = chr(2);
61 | variables.POSITIONAL_DELIMITER_MARKER = chr(3);
62 |
63 |
64 | /**
65 | * Initialization routine. Returns an instance of this component
66 | * @output false
67 | */
68 | public any function init()
69 | {
70 | if(!structisempty(arguments))
71 | {
72 | structappend(variables,arguments,"yes");
73 | }
74 | return this;
75 | }
76 |
77 |
78 | /**
79 | * Inserts a named sql param into sqlParams array. If the named param is not found, an exception is thrown
80 | *
81 | * @param1 namedparam
82 | * @param2 namedparamsarray Array containing all named sql params
83 | * @param3 sqlParams Array containing all sql queryparams supplied
84 | * @return array with the sqlParams inserted
85 | *
86 | * @output false
87 | */
88 | private array function insertNamedParams(string namedparam,array namedparamsarray,array sqlParams,string sql)
89 | {
90 | var i = 0;
91 | var foundNamedParam = false;
92 | for(i=1; i lte arraylen(namedparamsarray); i++)
93 | {
94 | if(structkeyexists(namedparamsarray[i],"name") and trim(namedparamsarray[i]["name"]) eq namedparam)
95 | {
96 | arrayappend(sqlParams,duplicate(namedparamsarray[i]));
97 | /*
98 | Delete "name" attribute for this entry (named param) from sqlParams array as we no longer need it, and besides,
99 | sending it to cfqueryparam with the name attribute would throw an error since allowExtraAttribute=false
100 | */
101 | structdelete(sqlParams[arraylen(sqlParams)],"name");
102 | foundNamedParam = true;
103 | break;
104 | }
105 | }
106 | if(!foundNamedParam)
107 | {
108 | var errorDetail = "Parameter '" & namedparam & "' not found in the list of parameters specified" & "
" & "SQL: " & sql;
109 | throw(errorMessage,errorType,errorDetail);
110 | }
111 | return sqlParams;
112 | }
113 |
114 |
115 | /**
116 | * Processes named sql params. Invokes insertNamedParams() to insert the named param into sqlparams array.
117 | *
118 | * @param1 sqlArray
119 | * @param2 sqlParams
120 | * @param3 namedparamsarray Array containing all named sql params
121 | * @param4 queryparams Array containing all sql queryparams supplied
122 | * @param5 sqlCommand Sql operation to perform
123 | * @return struct with sqlArray and sqlParams
124 | *
125 | * @output false
126 | */
127 | private struct function processNamedParams(array sqlArray,array sqlParams,array namedparamsarray,array queryparams,string sqlCommand,string sql)
128 | {
129 | var namedparam = "";
130 | var i = 0;
131 | if(arraylen(sqlArray) gt 0)
132 | {
133 | for(i=2; i <= arraylen(sqlArray); i++)
134 | {
135 | var delimters = SPACE & COMMA & RIGHTPARENTHESIS & NEWLINE;
136 | namedparam = trim(listfirst(sqlArray[i],delimters));
137 | sqlArray[i] = replace(arguments.sqlArray[i],namedparam,EMPTYSTRING);
138 | sqlParams = insertNamedParams(namedparam,namedparamsarray,sqlParams,sql);
139 | }
140 | }
141 | return {sqlArray=sqlArray,sqlParams=sqlParams};
142 | }
143 |
144 |
145 | /**
146 | * Removes first positional param from positional sql params array
147 | *
148 | * @param1 posparamsarray An array with positional sql params
149 | * @return array with first positional sql param removed
150 | *
151 | * @output false
152 | */
153 | private array function removePosParam(array posparamsarray)
154 | {
155 | var newPosParamsArray = [];
156 | var i = 0;
157 |
158 | //create a temp array from posparamsarray without the first element
159 | for(i=2;i lte arraylen(posparamsarray); i++)
160 | {
161 | newPosParamsArray[i-1] = posparamsarray[i];
162 | }
163 | return newPosParamsArray;
164 | }
165 |
166 |
167 | /**
168 | * Processes positional sql params
169 | *
170 | * @param1 sqlArray
171 | * @param1 sqlParams
172 | * @param1 posparamsarray An array with all positional params
173 | * @param1 queryparams An array with all queryparams the user supplied
174 | * @return struct with keys sqlArray and sqlParams
175 | *
176 | * @output false
177 | */
178 | private struct function processPosParams(array sqlArray,array sqlParams,array posparamsarray,array queryparams,string sql)
179 | {
180 | if(arraylen(sqlArray) gt 0)
181 | {
182 | if(arraylen(queryparams) lt arraylen(sqlArray)-1)
183 | {
184 | var errorDetail = "The number of parameters specified do not match the number of specified or implied columns" & "
" & "SQL: " & sql;
185 | throw(errorMessage,errorType,errorDetail);
186 | }
187 |
188 | var j = 0;
189 | //loop until all positional sql params are processed
190 | for(j=1;j lte arraylen(sqlArray); j++)
191 | {
192 | if(arraylen(posparamsarray) gt 0)
193 | {
194 | arrayappend(sqlParams,posparamsarray[1]);
195 | }
196 | //remove the postional sql param from the posparamsarray array
197 | posparamsarray = removePosParam(posparamsarray);
198 | }
199 | }
200 | return {sqlArray=sqlArray,sqlParams=sqlParams};
201 | }
202 |
203 |
204 | /**
205 | * Merge one array into another at a specified position and returns the merged array
206 | *
207 | * @param1 sqlArray1 Array into which to insert
208 | * @param2 sqlArray2 Array to be inserted
209 | * @param2 pos Position at which to insert
210 | * @return array (merged)
211 | *
212 | * @output false
213 | */
214 | private array function arrayinsert(array sqlArray1, array sqlArray2, numeric pos)
215 | {
216 | var mergedArray = [];
217 | var i = 0;
218 |
219 | //copy array sqlArray1 elements until pos-1 into mergedArray
220 | for(i=1; i lte pos-1; i++)
221 | {
222 | arrayappend(mergedArray,sqlArray1[i]);
223 | }
224 |
225 | //copy sqlArray2 into mergedArray
226 | for(i=1; i lte arraylen(arguments.sqlArray2); i++)
227 | {
228 | arrayappend(mergedArray,sqlArray2[i]);
229 | }
230 |
231 | //copy the remainder of sqlArray1 elements
232 | for(i=pos+1; i lte arraylen(sqlArray1); i++)
233 | {
234 | arrayappend(mergedArray,sqlArray1[i]);
235 | }
236 |
237 | //return the merged array
238 | return mergedArray;
239 | }
240 |
241 |
242 | /**
243 | * Checks if a named sql param exists in namedparams array.
244 | *
245 | * @param1 namedparams named sql params array
246 | * @param2 currentnamedparam named param to search in the array
247 | * @return Position at which the named param is found or false otherwise
248 | *
249 | * @output false
250 | */
251 | private boolean function checkIfNamedParamExists(array namedSqlparams, string namedparam)
252 | {
253 | var i = 0;
254 | for(i=1; i lte arraylen(namedSqlparams)-1; i++)
255 | {
256 | if(structkeyexists(namedSqlparams[i],"name") and trim(namedSqlparams[i]["name"]) eq namedparam)
257 | {
258 | return i;
259 | }
260 | }
261 | return false;
262 | }
263 |
264 |
265 | /**
266 | * parse queryparams stored in parameters array to filter out all named sql params.
267 | *
268 | * @param1 queryparams An array containing all queryparams
269 | * @return array containing all named sql params
270 | *
271 | * @output false
272 | */
273 | private array function getNamedSqlParams(array queryparams)
274 | {
275 | var namedSqlParams = [];
276 | var i = 0;
277 |
278 | for(i=1; i lte arraylen(queryparams); i++)
279 | {
280 | if(structkeyexists(queryparams[i],"name"))
281 | {
282 | //If named sql param already exists, update it. Else, add it
283 | var namedparam = trim(queryparams[i]["name"]);
284 | var found = checkIfNamedParamExists(namedSqlParams,namedparam);
285 | if(!found)
286 | {
287 | //insert the queryparam into the namedSqlParams array
288 | arrayappend(namedSqlParams,queryparams[i]);
289 | }
290 | else
291 | {
292 | //since the named param already exists, update its value
293 | structappend(namedSqlParams[found],queryparams[i],"yes");
294 | }
295 | }
296 | }
297 | return namedSqlParams;
298 | }
299 |
300 |
301 | /**
302 | * parse queryparams stored in parameters array to filter out all postional sql params.
303 | *
304 | * @param1 queryparams An array containing all queryparams
305 | * @return array containing all positional sql params
306 | *
307 | * @output false
308 | */
309 | private array function getPositionalSqlParams(array queryparams)
310 | {
311 | var positionalSqlParams = [];
312 | var i = 0;
313 | for(i=1; i lte arraylen(queryparams); i++)
314 | {
315 | //if there is no "name" key in the queryparam, it is a positional sql param
316 | if(!structkeyexists(queryparams[i],"name"))
317 | {
318 | //insert the queryparam into the positionalSqlParams array
319 | arrayappend(positionalSqlParams,queryparams[i]);
320 | }
321 | }
322 | return positionalSqlParams;
323 | }
324 |
325 |
326 | /**
327 | * replace named and positional delimiters inside single quotes with corresponding markers to allow parsing SQL on delimiters
328 | * @output false
329 | */
330 | private string function replaceDelimsWithMarkers(string sql, string sqlDelimtersList, string sqlDelimtersMarkersList)
331 | {
332 | var sqlArray = listtoarray(arguments.sql,SINGLEQUOTE,true);
333 | var newSql = "";
334 | var i = 0;
335 | for(i=1; i lte arraylen(sqlArray); i++)
336 | {
337 | //even numbered array indices contain value inside the single quotes
338 | //replace occurence of named or positional delimiters in the value with corresponding markers
339 | if( (i%2) eq 0 )
340 | {
341 | sqlArray[i] = ReplaceList(sqlArray[i],sqlDelimtersList,sqlDelimtersMarkersList);
342 | newSql = newSql & SINGLEQUOTE & sqlArray[i] & SINGLEQUOTE & " ";
343 | }
344 | else
345 | {
346 | newSql = newSql & sqlArray[i];
347 | }
348 | }
349 | return newSql;
350 | }
351 |
352 |
353 | /**
354 | * Replaces markers for named and positional delimiters (inside single quotes) with actual delimiters
355 | *
356 | * @param1 sqlArray Array with parsed sql
357 | * @return array Array with markers replaced with single quotes
358 | *
359 | * @output false
360 | */
361 | private array function replaceMarkersWithDelims(array sqlArray, string sqlDelimtersMarkersList, string sqlDelimtersList)
362 | {
363 | var i = 0;
364 | for(i=1; i lte arraylen(sqlArray); i++)
365 | {
366 | sqlArray[i] = ReplaceList(sqlArray[i],sqlDelimtersMarkersList,sqlDelimtersList);
367 | }
368 | return sqlArray;
369 | }
370 |
371 |
372 | /**
373 | * preservesinglequotes() can't handle expressions, so something like #preservesinglequotes(SQlArray[1])# would'nt work,
374 | * hence the need for this wrapper
375 | * @output false
376 | */
377 | private string function getPreserveSingleQuotes(string sqlstatement)
378 | {
379 | return PreserveSingleQuotes(arguments.sqlstatement);
380 | }
381 |
382 |
383 | /**
384 | * Parse the SQL into named and positional params.
385 | *
386 | * For named params, order of params is not important but for postional params we need to match
387 | * the order in which the params are listed.
388 | *
389 | * Named SQL parameters are specified using ":" (for example, select * from art where artid = :artistid)
390 | * Positional SQL parameters are specified using "?" (for example, select * from art where artid = ? and artistid = ?)
391 | *
392 | * A combination of named and positional sql params is also possible (although not encouraged)
393 | * (for example, select * from art where artid = :artid and artistid = ?)
394 | *
395 | * If named/positional param delimiters (i.e. ":" and "?") appear inside single quotes, we replace them with markers
396 | * to help with the parsing. After we are done with the parsing and before we pass the sql to execute() for execution, we replace the markers back with
397 | * the delimiters
398 | *
399 | * This function parses the sql into sqlArray[] and sqlParams[]
400 | *
401 | * @param1 sql The sql used in the query
402 | * @param2 queryparams The queryparams for the query
403 | * @param3 sqlCommand The sql operation to perform
404 | * @return A struct with keys - sqlType (named/param/both), sqlArray (sql parsed into array) and sqlParams (queryparams parsed into array of structs)
405 | *
406 | * @output false
407 | */
408 | private any function parseSQL(string sql,array queryparams,string sqlCommand)
409 | {
410 | //type of sql (named | positional | both | "" (for simple SQL))
411 | var sqlType = "";
412 |
413 | //sql delimiter (: -> named, ? -> positional)
414 | var delimiter = "";
415 |
416 | //array to store parsed sql
417 | var sqlArray = [];
418 |
419 | //array to store parsed sql queryparams
420 | var sqlParams = [];
421 |
422 | //markers used to replace named or positional parameters found inside single quotes or ''
423 | var sqlDelimtersList = NAMED_DELIMITER & "," & POSITIONAL_DELIMITER;
424 | var sqlDelimtersMarkersList = NAMED_DELIMITER_MARKER & "," & POSITIONAL_DELIMITER_MARKER;
425 |
426 | //replace occurences of any named or positional delimters inside single quotes with markers since we are dealing with a value rather than a sql param
427 | var mysql = replaceDelimsWithMarkers(sql,sqlDelimtersList,sqlDelimtersMarkersList);
428 | var param = [];
429 |
430 | //parse queryparams (stored in paramters array) into named sql params and positional sql params
431 | var namedparamsarray = getNamedSqlParams(queryparams);
432 | var posparamsarray = getPositionalSqlParams(queryparams);
433 |
434 | //if the sql has both named and positional params, we first parse the sql for positional params, and then for named params
435 | if(mysql contains NAMED_DELIMITER and mysql contains POSITIONAL_DELIMITER)
436 | {
437 | sqlType = "both";
438 | delimiter = POSITIONAL_DELIMITER;
439 | }
440 | else if(mysql contains NAMED_DELIMITER and not (mysql contains POSITIONAL_DELIMITER))
441 | {
442 | sqlType = "namedSql";
443 | delimiter = NAMED_DELIMITER;
444 | }
445 | else if(mysql contains POSITIONAL_DELIMITER and not (mysql contains NAMED_DELIMITER))
446 | {
447 | sqlType = "posSql";
448 | delimiter = POSITIONAL_DELIMITER;
449 | }
450 | else
451 | {
452 | sqlType = "";
453 | delimiter = "";
454 | }
455 |
456 | //convert sql into an array. If there are no named/positional params, the array would consist of merely the sql but if there are params, we use the delimiter
457 | sqlArray = (delimiter eq "")? [mysql]: listtoarray(mysql,delimiter,true,true);
458 |
459 | switch(sqlType)
460 | {
461 | //we are dealing with postional sql parameters
462 | case "posSql":
463 | {
464 | var s = processPosParams(sqlArray,sqlParams,posparamsarray,queryparams,sql);
465 | sqlArray = s["sqlArray"];
466 | sqlParams = s["sqlParams"];
467 | break;
468 | }
469 |
470 | //we are dealing with named sql parameters
471 | case "namedSql":
472 | {
473 | s = processNamedParams(sqlArray,sqlParams,namedparamsarray,queryparams,sqlCommand,sql);
474 | sqlArray = s["sqlArray"];
475 | sqlParams = s["sqlParams"];
476 | break;
477 | }
478 |
479 | //we are dealing with a combination of both named and positional sql parameters
480 | case "both":
481 | {
482 | continueloop = true;
483 | var i = 1;
484 |
485 | //loop until we are finished with sqlArray[], which grows dynamically as we continue processing the params
486 | while(continueloop eq true)
487 | {
488 | //this is a positional sql param that we are dealing with here
489 | if(sqlArray[i] does not contain NAMED_DELIMITER)
490 | {
491 | if(i lt arraylen(sqlArray))
492 | {
493 | if(arraylen(posparamsarray) gt 0)
494 | {
495 | arrayappend(sqlParams,posparamsarray[1]);
496 | }
497 | posparamsarray = removePosParam(posparamsarray);
498 | }
499 | i = i + 1;
500 | }
501 | else
502 | {
503 | //this is a named sql param that we are dealing with here
504 | var temp = processNamedParams(listtoarray(sqlArray[i],NAMED_DELIMITER),sqlParams,namedparamsarray,queryparams,sqlCommand,sql);
505 | param = temp["sqlArray"];
506 | sqlParams = temp["sqlParams"];
507 |
508 | //insert array param into sqlArray at postion i and returns the new merged array
509 | sqlArray = arrayinsert(sqlArray,param,i);
510 |
511 | //since we are already done with processing the param array, we skip past it and resume our processing
512 | i = i + arraylen(param);
513 | if(i lte arraylen(sqlArray))
514 | {
515 | if(arraylen(posparamsarray) gt 0)
516 | {
517 | arrayappend(sqlParams,posparamsarray[1]);
518 | }
519 | posparamsarray = removePosParam(posparamsarray);
520 | }
521 | }
522 | if(i gt arraylen(sqlArray))
523 | {
524 | continueloop=false;
525 | }
526 | }
527 | break;
528 | }
529 | default:
530 | {
531 | sqlArray = [mysql];
532 | break;
533 | }
534 | }
535 |
536 | //replace markers for named and positional delimiters with actual delimiters
537 | sqlArray = replaceMarkersWithDelims(sqlArray,sqlDelimtersMarkersList,sqlDelimtersList);
538 |
539 | //return a struct with the parsed array and parsed queryparams back
540 | return {sqlArray=sqlArray,sqlParams=sqlParams,sqlType=sqlType};
541 | }
542 |
543 |
544 |
545 | /**
546 | * Validate SQL for errors
547 | * @return SQL or an error if SQL has errors
548 | * @output false
549 | */
550 | private string function validateSQL(struct tagAttributes)
551 | {
552 | var sql = "";
553 | var errorDetail = "";
554 |
555 | //throw an error if SQL is not defined
556 | if(not structkeyexists(tagAttributes,"sql"))
557 | {
558 | errorDetail = "SQL is required";
559 | throw(errorMessage,errorType,errorDetail);
560 | }
561 | else
562 | {
563 | sql = tagAttributes["sql"];
564 | //throw an error if SQL is empty
565 | if(len(trim(sql)) eq 0)
566 | {
567 | errorDetail = "The value of SQL cannot be empty";
568 | throw(errorMessage,errorType,errorDetail);
569 | }
570 | }
571 | return sql;
572 | }
573 |
574 |
575 | /**
576 | * Invoke the cfquery (and cfqueryparam) service tag to execute a query in cfscript. Returns the query resultset
577 | * @output false
578 | */
579 | public result function execute()
580 | {
581 | //store tag attributes to be passed to the service tag in a local variable
582 | var tagAttributes = duplicate(getTagAttributes());
583 |
584 | //store query params
585 | var queryparams = duplicate(variables.parameters);
586 |
587 | //attributes passed to service tag action like execute() override existing attributes and are discarded after the action
588 | if(!structisempty(arguments))
589 | {
590 | structappend(tagAttributes,arguments,"yes");
591 | }
592 |
593 | //extract SQL from attributes and validate it for errors
594 | var sql = validateSQL(tagAttributes);
595 |
596 | //remove leading and trailing parenthesis for stored procs called using {CALL myproc 1,2}
597 | if(left(sql,1) eq "{" and right(sql,1) eq "}")
598 | {
599 | sql = trim(mid(sql,2,len(sql)-2));
600 | }
601 |
602 | //sql operation to perform (Select | update | insert | delete | exec | call)
603 | var sqlCommand = ucase(listfirst(sql," "));
604 |
605 | //parse SQL and process queryparams, if defined
606 | var r = parseSQL(sql,queryparams,sqlCommand);
607 | var sqlType = r["sqlType"];
608 | var sqlArray = r["sqlArray"];
609 | var sqlParams = r["sqlParams"];
610 |
611 | //put back leading and trailing parenthesis for stored procs called using {CALL myproc 1,2}
612 | if(sqlCommand eq "CALL")
613 | {
614 | sqlArray[1] = "{" & sqlArray[1];
615 | sqlArray[arraylen(sqlArray)] = sqlArray[arraylen(sqlArray)] & "}";
616 | }
617 |
618 | //looks like query name attribute isn't really required, so we give the query a name in case one is not specified
619 | if(!structkeyexists(tagAttributes,"name") or (structkeyexists(tagAttributes,"name") and tagAttributes["name"] eq ""))
620 | {
621 | tagAttributes["name"] = "qryname#randrange(1,100000)#";
622 | }
623 |
624 | //should we do the same for result attribute also?
625 | if(!structkeyexists(tagAttributes,"result") or (structkeyexists(tagAttributes,"result") and tagAttributes["result"] eq ""))
626 | {
627 | tagAttributes["result"] = "qryresult#randrange(1,100000)#";
628 | }
629 |
630 | //delete sql attribute since passing it would execute the sql which is not what we want as we are preparsing the sql
631 | if(structkeyexists(tagAttributes,"sql"))
632 | {
633 | structdelete(tagAttributes,"sql");
634 | }
635 |
636 | //trim attribute values
637 | tagAttributes = trimAttributes(tagAttributes);
638 |
639 | //invoke the cfquery/cfqueryparam tags replacing any named or positional params with cfqueryparam tag
640 | return super.invokeTag(getTagName(),tagAttributes,{params=sqlParams,sqlArray=sqlArray,sql=sql,sqlType=sqlType});
641 | }
642 | }
--------------------------------------------------------------------------------
/queryofqueries.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 | #preserveSingleQuotes(arguments.SQL)#
28 |
29 |
30 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # ColdFusion 9+ Script Components
2 | ## Community Edition!
3 |
4 | The components in this project are contributed by the ColdFusion community, for the ColdFusion Community.
5 |
6 | ### Installing...
7 |
8 | You can simply [download the zip](https://github.com/CFCommunity/CFScript-Community-Components/zipball/master) of the available components and toss them in the appropriate directory, if you want. (`{cf-install}\CustomTags\com\adobe\coldfusion\`)
9 |
10 | It would be easier to update if you use git:
11 |
12 | 1. Open a terminal prompt at the above directory
13 | 1. Run this: `git init;git remote add origin git://github.com/CFCommunity/CFScript-Community-Components.git;git pull`
14 | 1. Any time you want to update, simply (go into that directory and) run `git pull`
15 |
16 | # Deficiencies!
17 |
18 | These are the tags that need to be ported over to script. Godspeed!
19 |
20 | ## Significant omissions:
21 |
22 | * cfexchangecalendar
23 | * cfexchangeconnection
24 | * cfexchangecontact
25 | * cfexchangefilter
26 | * cfexchangemail
27 | * cfexchangetask
28 | * cfmodule
29 | * cfoutput (implementation of query looping with grouping)
30 | * cfparam (fix the bug in that enforced requiredness doesn’t work (ie: param name="foo";))
31 | * cfquery (cachedwithin support)
32 |
33 | ## Reasonable case
34 |
35 | * cfassociate
36 | * cfcache
37 | * cfprint
38 | * cfsharepoint
39 | * cftimer
40 |
41 | ## Ambivalent
42 |
43 | * cfgridupdate
44 | * cfinsert
45 | * cflogin
46 | * cfreport
47 | * cfreportparam
48 | * cfupdate
49 |
50 | # Adobe copyright...
51 |
52 | The following components ship with CF9 and CF9.01. Adobe holds copyright on them, but has granted permission to modify and distribute under an unspecified license, the text of which is below the list. Unless modified to support additional functionality or fix any bugs that may arise, they are not included in this repository. Any time they are changed, you can be sure tremendous effort has been made to maintain compatibility and, unless noted somewhere in this readme, has been achieved.
53 |
54 | * base.cfc
55 | * dbinfo.cfc
56 | * feed.cfc
57 | * ftp.cfc
58 | * http.cfc
59 | * imap.cfc
60 | * ldap.cfc
61 | * mail.cfc
62 | * pdf.cfc
63 | * pop.cfc
64 | * query.cfc
65 | * result.cfc
66 | * storedproc.cfc
67 | * storedprocresult.cfc
68 |
69 | ## Adobe license
70 |
71 | This license text is taken from the components that ship with Adobe ColdFusion 9 and applies only to those components.
72 |
73 | >ADOBE CONFIDENTIAL
74 | >___________________
75 | >
76 | >Copyright 2008 Adobe Systems Incorporated
77 | >All Rights Reserved.
78 | >
79 | >NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms of the Adobe license agreement accompanying it. If you have received this file from a source other than Adobe, then your use, modification, or distribution of it requires the prior written permission of Adobe.
80 |
81 | # MIT License
82 |
83 | >Copyright (c) 2011 The ColdFusion Community
84 | >
85 | >Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
86 | >
87 | >The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
88 | >
89 | >THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
90 |
91 | See also: [http://www.opensource.org/licenses/mit-license.html](http://www.opensource.org/licenses/mit-license.html)
92 |
93 | # Hey Adobe!
94 |
95 | You are welcome, and encouraged, to ship these in future versions of ColdFusion. Please do, at least where appropriate. In some cases it just doesn't look and feel right to use CFCs to make these features. When that's the case, they are included here only as a stop-gap so that we can _actually write full-script components_. Please, where it makes sense, still write the features in Java. But where this implementation looks and feels natural, by all means, run with it! It'll make life better for everyone!
--------------------------------------------------------------------------------
/registry.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/schedule.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/search.cfc:
--------------------------------------------------------------------------------
1 | /***********************************************************************************************************
2 | *
3 | * Made by Raymond Camden, Jedi Master
4 | *
5 | * MIT License
6 | *
7 | * Copyright (c) 2011 The ColdFusion Community
8 | *
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
10 | * associated documentation files (the "Software"), to deal in the Software without restriction, including
11 | * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
13 | * following conditions:
14 | *
15 | * The above copyright notice and this permission notice shall be included in all copies or substantial
16 | * portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
19 | * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
20 | * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 | *
24 | * See also: http://www.opensource.org/licenses/mit-license.html
25 | *
26 | *************************************************************************************************************/
27 |
28 | /**
29 | * Search Service to perform search operations in cfscript
30 | * @name search
31 | * @displayname ColdFusion Search Service
32 | * @output false
33 | * @accessors true
34 | */
35 | component extends="base" {
36 |
37 | property string collection;
38 | //property string name;
39 | property string category;
40 | property string categoryTree;
41 | property numeric contextBytes;
42 | property string contextHighlightBegin;
43 | property string contextHighlightEnd;
44 | property numeric contextPassages;
45 | property string criteria;
46 | //Language is deprecated
47 | property numeric maxRows;
48 | property string previousCriteria;
49 | property numeric startRow;
50 | property string status;
51 | property string suggestions;
52 | property string orderby;
53 | //Type is deprecated
54 |
55 | property name="properties" type="any" getter="false" setter="false";
56 |
57 | //service tag to invoke
58 | variables.tagName = "CFSEARCH";
59 |
60 | //cffeed tag attributes
61 | variables.tagAttributes = getSupportedTagAttributes(getTagName());
62 |
63 | /**
64 | * Default constructor invoked when search objects are created.
65 | * @return search object
66 | * @output false
67 | */
68 | public search function init()
69 | {
70 | if(!structisempty(arguments)) structappend(variables,arguments);
71 | return this;
72 | }
73 |
74 | /**
75 | * Invoke the cfsearch service tag to search solr collections in cfscript
76 | * Usage :: new search().search(criteria="foo",maxRows=10);
77 | * @output false
78 | */
79 | public struct function search()
80 | {
81 | //store tag attributes to be passed to the service tag in a local variable
82 | var tagAttributes = duplicate(getTagAttributes());
83 |
84 | //attributes passed to service tag action like send() override existing attributes and are discarded after the action
85 | if (!structisempty(arguments))
86 | {
87 | structappend(tagAttributes,arguments);
88 | }
89 |
90 | //trim attribute values
91 | tagAttributes = trimAttributes(tagAttributes);
92 |
93 | return super.invokeTag(getTagName(),tagAttributes);
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/setting.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/spreadsheet.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/tests/ExecuteTest.cfc:
--------------------------------------------------------------------------------
1 | component extends="mxunit.framework.TestCase" {
2 |
3 | variables.NixOSList = "Mac OS X";
4 | variables.noTestError = "The platform [#server.os.name#] is not in the executeTest server list, or there are no tests written for it yet.";
5 |
6 | public function testDate(){
7 | var commandline = createObject("component", "CFScript-Community-Components.execute").init();
8 |
9 | if (ListFind(server.OS.name, variables.NixOSList) > 0){
10 | commandline.setName("date");
11 | commandline.setArguments("+%Y-%m-%d-%H-%M-%S");
12 | commandline.setTimeout(5);
13 | var result = commandline.execute();
14 | var actual = result.getResult().result;
15 | var now = now();
16 | var expected = DateFormat(now, "yyyy-mm-dd-") & TimeFormat(now, "HH-mm-ss");
17 | AssertTrue(Len(result.getResult().result) > 0);
18 | AssertTrue(Len(result.getResult().error) == 0);
19 | AssertEquals(expected, actual);
20 | }
21 | else{
22 | fail(variables.noTestError);
23 | }
24 |
25 | }
26 |
27 | public function testExecuteError(){
28 | var commandline = createObject("component", "CFScript-Community-Components.execute").init();
29 |
30 | if (ListFind(server.OS.name, variables.NixOSList) > 0){
31 | commandline.setName("ls");
32 | commandline.setArguments("/null");
33 | commandline.setTimeout(5);
34 | var result = commandLine.execute();
35 | AssertTrue(Len(result.getResult().result) == 0);
36 | AssertTrue(Len(result.getResult().error) > 0);
37 | var actual = commandline.execute().getResult().error;
38 | var expected = "ls: /null: No such file or directory";
39 | AssertEquals(expected, actual);
40 | }
41 | else{
42 | fail(variables.noTestError);
43 | }
44 |
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/tests/LoginFrameworkTest.cfc:
--------------------------------------------------------------------------------
1 | component extends="mxunit.framework.TestCase" {
2 |
3 | function testLoginLogout() {
4 | assertFalse(isUserLoggedIn());
5 | assertFalse(isUserInAnyRole("role,otherRole"));
6 | assertFalse(isUserInRole("role"));
7 |
8 | createObject("component", "CFScript-Community-Components.loginuser").init("everybody","secretpassword","role");
9 |
10 | assertTrue(isUserLoggedIn());
11 | assertTrue(isUserInAnyRole("role,otherRole"));
12 | assertTrue(isUserInRole("role"));
13 | assertFalse(isUserInRole("otherRole"));
14 |
15 | createObject("component", "CFScript-Community-Components.logout").init();
16 |
17 | assertFalse(isUserLoggedIn());
18 | assertFalse(isUserInAnyRole("role,otherRole"));
19 | assertFalse(isUserInRole("role"));
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/tests/SpreadsheetTest.cfc:
--------------------------------------------------------------------------------
1 | component extends="mxunit.framework.TestCase" {
2 |
3 |
4 | function testSpreadsheet() {
5 | var spreadsheet = createObject("component", "CFScript-Community-Components.spreadsheet");
6 |
7 | var testFile = getTempDirectory() & "spreadsheet-unittest.xls";
8 | if(fileExists(testFile)) {
9 | fileDelete(testFile);
10 | }
11 |
12 | var dataToWrite = queryNew("ColumnA,ColumnB,ColumnC");
13 | queryAddRow(dataToWrite, 3);
14 | dataToWrite.ColumnA[1] = "One";
15 | dataToWrite.ColumnB[1] = 1;
16 | dataToWrite.ColumnC[1] = "Uno";
17 | dataToWrite.ColumnA[2] = "Two";
18 | dataToWrite.ColumnB[2] = 2;
19 | dataToWrite.ColumnC[2] = "Dos";
20 | dataToWrite.ColumnA[3] = "Three";
21 | dataToWrite.ColumnB[3] = 3;
22 | dataToWrite.ColumnC[3] = "Tres";
23 |
24 | spreadsheet.write(
25 | filename = testFile,
26 | query = dataToWrite
27 | );
28 |
29 | var spreadsheetInfo = spreadsheet.readInfo(
30 | src = testFile
31 | );
32 |
33 | assertTrue(structKeyExists(spreadsheetInfo, "summaryInfo"));
34 | assertEquals(spreadsheetInfo.summaryInfo.sheets, 1);
35 |
36 | spreadsheet.update(
37 | filename = testfile,
38 | query = dataToWrite,
39 | sheetname = "blah"
40 | );
41 |
42 | var spreadsheetInfo = spreadsheet.readInfo(
43 | src = testFile
44 | );
45 |
46 | assertTrue(structKeyExists(spreadsheetInfo, "summaryInfo"));
47 | assertEquals(spreadsheetInfo.summaryInfo.sheets, 2);
48 |
49 |
50 | var spreadsheetData = spreadsheet.readQuery(
51 | src = testfile,
52 | excludeHeaderRow = true,
53 | headerRow = 1
54 | );
55 |
56 | assertTrue(isQuery(spreadsheetData));
57 | assertEquals(spreadsheetData.ColumnA[3], "Three");
58 |
59 | if(fileExists(testFile)) {
60 | fileDelete(testFile);
61 | }
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/tests/queryofqueriesTest.cfc:
--------------------------------------------------------------------------------
1 | component extends="mxunit.framework.TestCase" {
2 |
3 | private struct function getTestData() {
4 | var queries = {};
5 | // Set up two test queries
6 | var q1 = queryNew("id,value");
7 | queryAddRow(q1);
8 | querySetCell(q1, "id", 1);
9 | querySetCell(q1, "value", "loo");
10 | queryAddRow(q1);
11 | querySetCell(q1, "id", 2);
12 | querySetCell(q1, "value", "foo");
13 | queryAddRow(q1);
14 | querySetCell(q1, "id", 3);
15 | querySetCell(q1, "value", "zoo");
16 |
17 | var q2 = queryNew("id,othervalue");
18 | queryAddRow(q2);
19 | querySetCell(q2, "id", 1);
20 | querySetCell(q2, "othervalue", "boo");
21 | queryAddRow(q2);
22 | querySetCell(q2, "id", 3);
23 | querySetCell(q2, "othervalue", "too");
24 | queryAddRow(q2);
25 | querySetCell(q2, "id", 44);
26 | querySetCell(q2, "othervalue", "moo");
27 |
28 | queries.q1 = q1;
29 | queries.q2 = q2;
30 | return queries;
31 | }
32 |
33 | function testQueryOfQueries() {
34 | data = getTestData();
35 |
36 | // This is how you use the QoQ component
37 | var queryResults = createObject("component", "CFScript-Community-Components.queryofqueries").init(
38 | SQL = "select * from q1, q2 where q1.id = q2.id",
39 | q1 = data.q1,
40 | q2 = data.q2
41 | );
42 |
43 | assertEquals(queryResults.recordcount, 2);
44 |
45 | var queryResults = createObject("component", "CFScript-Community-Components.queryofqueries").init(
46 | SQL = "select * from q1 where id = 2",
47 | q1 = data.q1,
48 | q2 = data.q2
49 | );
50 |
51 | assertEquals(queryResults.recordcount, 1);
52 |
53 | var queryResults = createObject("component", "CFScript-Community-Components.queryofqueries").init(
54 | SQL = "select * from q1, q2 where q1.id = q2.id and q1.id < 4",
55 | q1 = data.q1,
56 | q2 = data.q2
57 | );
58 |
59 | assertEquals(queryResults.recordcount, 2);
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/wddx.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/zip.cfc:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------