bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
ff_ce_functions.cc
1
2// -*- mode: c++; c-basic-offset:4 -*-
3
4// This file is part of ff_handler a FreeForm API handler for the OPeNDAP
5// DAP2 data server.
6
7// Copyright (c) 2005 OPeNDAP, Inc.
8// Author: James Gallagher <jgallagher@opendap.org>
9//
10// This is free software; you can redistribute it and/or modify it under the
11// terms of the GNU Lesser General Public License as published by the Free
12// Software Foundation; either version 2.1 of the License, or (at your
13// option) any later version.
14//
15// This software is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18// License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23//
24// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25
26// (c) COPYRIGHT URI/MIT 1998-1999
27// Please read the full copyright statement in the file COPYRIGHT.
28//
29// Authors:
30// jhrg,jimg James Gallagher (jgallagher@gso.uri.edu)
31
32// This file contains various functions for use with/in constraint
33// expressions.
34
35#include <iostream>
36#include <string>
37#include <algorithm>
38
39//#define DODS_DEBUG
40
41#include <libdap/BaseType.h>
42#include <libdap/Str.h>
43#include <libdap/Structure.h>
44#include <libdap/Sequence.h>
45#include <libdap/DDS.h>
46#include <libdap/ConstraintEvaluator.h>
47#include <libdap/ServerFunctionsList.h>
48#include <libdap/Error.h>
49#include <libdap/util.h>
50#include <libdap/debug.h>
51
52#include "date_proc.h"
53#include "DODS_Date.h"
54#include "DODS_Date_Factory.h"
55#include "DODS_StartDate_Factory.h"
56#include "DODS_EndDate_Factory.h"
57#include "DODS_Time.h"
58#include "DODS_Time_Factory.h"
59#include "DODS_StartTime_Factory.h"
60#include "DODS_EndTime_Factory.h"
61#include "DODS_Date_Time.h"
62#include "DODS_Date_Time_Factory.h"
63#include "DODS_StartDate_Time_Factory.h"
64#include "DODS_EndDate_Time_Factory.h"
65
66#include "ff_ce_functions.h"
67#include "FFStr.h"
68
73
74template < class T, class T_Factory >
75inline static T get_instance(DDS & dds)
76{
77 return T_Factory(dds).get();
78}
79
92
93template < class T, class T_Factory >
94static bool comparison(int argc, BaseType * argv[], DDS & dds)
95{
96 if (argc < 1 || argc > 2)
97 throw Error(malformed_expr,
98 "Wrong number of arguments to a constraint expression function.");
99
100 DBG(cerr << "comparision: argc: " << argc << endl);
101
102 T t1(argv[0]);
103 T t2;
104 if (argc == 2)
105 t2.set(argv[1]);
106
107 T current = get_instance < T, T_Factory > (dds);
108
109 DBG(cerr << "t1: " << t1.get(iso8601) << endl);
110 if (argc == 2) {
111 DBG(cerr << "t2 (1): " << t2.get(iso8601) << endl);
112 }
113 DBG(cerr << "current: " << current.get(iso8601) << endl);
114
115 if (argc == 2)
116 return ((t1 <= current) && (t2 >= current));
117 else
118 return (t1 == current);
119}
120
133
134template < class T1, class T1_Factory, class T2, class T2_Factory >
135 static bool range_comparison(int argc, BaseType * argv[], DDS & dds)
136{
137 if (argc != 2)
138 throw Error(malformed_expr,
139 "Wrong number of arguments to a constraint expression function.");
140
141 T1 t1(argv[0]);
142 T2 t2(argv[1]);
143
144 T1 current_start = get_instance < T1, T1_Factory > (dds);
145 T2 current_end = get_instance < T2, T2_Factory > (dds);
146
147 return (((current_start >= t1) && (current_start <= t2)) ||
148 ((current_end >= t1) && (current_end <= t2)) ||
149 ((current_start <= t1) && (current_end >= t2)));
150}
151
159
160static void
161new_string_variable(const string & name, DDS & dds, BaseType * position = 0)
162{
163 // Create the new variable
164
165 Str *new_variable = new FFStr(name, "");
166 new_variable->set_read_p(true); // You must call this before ...
167 new_variable->set_synthesized_p(true); // this! Look at BaseType.cc.
168
169 // Add it to the DDS in the right place
170
171 if (position) {
172 switch (position->type()) {
173 case dods_structure_c:{
174 Structure *sp = (Structure *) position;
175 sp->add_var((BaseType *) new_variable);
176 break;
177 }
178
179 case dods_sequence_c:{
180 Sequence *sp = (Sequence *) position;
181 sp->add_var((BaseType *) new_variable);
182 break;
183 }
184
185 default:
186 delete new_variable;
187 throw Error(malformed_expr,
188 "You asked me to insert the synthesized variable in \n\
189something that did not exist or was not a constructor \n\
190type (e.g., a structure, sequence, ...).");
191 break;
192 }
193 }
194 else {
195 dds.add_var(new_variable);
196 }
197
198 // Mark the variable as part of the current projection.
199
200 dds.mark(name, true); // Don't just call set_send_p()!
201
202 delete new_variable;
203}
204
205static void func_date(int argc, BaseType * argv[], DDS & dds, bool *result)
206{
207 DBG(cerr << "calling func_date" << endl);
208 *result = comparison < DODS_Date, DODS_Date_Factory > (argc, argv, dds);
209 DBG(cerr << "result: " << *result << endl << endl);
210}
211
212static void func_startdate(int argc, BaseType * argv[], DDS & dds, bool *result)
213{
214 DBG(cerr << "calling func_startdate" << endl);
215 *result = comparison < DODS_Date, DODS_StartDate_Factory > (argc, argv,
216 dds);
217}
218
219static void func_enddate(int argc, BaseType * argv[], DDS & dds, bool *result)
220{
221 DBG(cerr << "calling func_enddate" << endl);
222 *result = comparison < DODS_Date, DODS_EndDate_Factory > (argc, argv,
223 dds);
224}
225
226static void func_date_range(int argc, BaseType * argv[], DDS & dds, bool *result)
227{
228 *result = range_comparison < DODS_Date, DODS_StartDate_Factory, DODS_Date,
229 DODS_EndDate_Factory > (argc, argv, dds);
230}
231
232static void func_time(int argc, BaseType * argv[], DDS & dds, bool *result)
233{
234 *result = comparison < DODS_Time, DODS_Time_Factory > (argc, argv, dds);
235}
236
237static void func_starttime(int argc, BaseType * argv[], DDS & dds, bool *result)
238{
239 *result = comparison < DODS_Time, DODS_StartTime_Factory > (argc, argv,
240 dds);
241}
242
243static void func_endtime(int argc, BaseType * argv[], DDS & dds, bool *result)
244{
245 *result = comparison < DODS_Time, DODS_EndTime_Factory > (argc, argv,
246 dds);
247}
248
249// This comparision function should be used for decimal dates. 5/29/99 jhrg
250
251static void func_date_time(int argc, BaseType * argv[], DDS & dds, bool *result)
252{
253 *result = comparison < DODS_Date_Time, DODS_Date_Time_Factory > (argc,
254 argv,
255 dds);
256}
257
258static void func_startdate_time(int argc, BaseType * argv[], DDS & dds, bool *result)
259{
260 *result = comparison < DODS_Date_Time,
261 DODS_StartDate_Time_Factory > (argc, argv, dds);
262}
263
264static void func_enddate_time(int argc, BaseType * argv[], DDS & dds, bool *result)
265{
266 *result = comparison < DODS_Date_Time, DODS_EndDate_Time_Factory > (argc,
267 argv,
268 dds);
269}
270
271// This function is added to the selection part of the CE when the matching
272// `projection function' is run.
273
274// The date and date_time functions should now recognize decimal format years
275// and date-times. 5/30/99 jhrg
276
277static void sel_dods_jdate(int argc, BaseType *[], DDS & dds, bool *result)
278{
279 if (argc != 0)
280 throw Error(malformed_expr,
281 "Wrong number of arguments to internal selection function.\n\
282Please report this error.");
283
284 DODS_Date current =
285 get_instance < DODS_Date, DODS_Date_Factory > (dds);
286
287 // Stuff the yyyy/ddd string into DODS_JDate.
288 Str *dods_jdate = (Str *) dds.var("DODS_JDate");
289 // By calling DODS_Date::get with the token `yd' I'm explicitly asking
290 // for the year/day (pseudo juilian) date format. 5/27/99 jhrg
291 string s = current.get(yd).c_str();
292 dods_jdate->val2buf(&s);
293
294 *result = true;
295}
296
297// A projection function: This adds a new variable to the DDS and arranges
298// for the matching selection function (above) to be called.
299
300static void
301proj_dods_jdate(int argc, BaseType * argv[], DDS & dds,
302 ConstraintEvaluator & ce)
303{
304 if (argc < 0 || argc > 1)
305 throw Error(malformed_expr,
306 "Wrong number of arguments to projection function.\n\
307Expected zero or one arguments.");
308
309 new_string_variable("DODS_JDate", dds, (argc == 1) ? argv[0] : 0);
310
311 // Add the selection function to the CE
312
313 ce.append_clause(sel_dods_jdate, 0); // 0 == no BaseType args
314}
315
316// Same as the above function, but for ymd dates.
317
318static void sel_dods_date(int argc, BaseType *[], DDS & dds, bool *result)
319{
320 if (argc != 0)
321 throw Error(malformed_expr,
322 "Wrong number of arguments to internal selection function.\n\
323Please report this error.");
324
325 DODS_Date current =
326 get_instance < DODS_Date, DODS_Date_Factory > (dds);
327
328 // Stuff the yyyy/ddd string into DODS_Date.
329 Str *dods_date = (Str *) dds.var("DODS_Date");
330 // Calling the regular form of DODS_Date::get() returns the data in y/m/d
331 // format. 5/27/99 jhrg
332 string s = current.get().c_str();
333 dods_date->val2buf(&s);
334
335 *result = true;
336}
337
338static void
339proj_dods_date(int argc, BaseType * argv[], DDS & dds,
340 ConstraintEvaluator & ce)
341{
342 if (argc < 0 || argc > 1)
343 throw Error(malformed_expr,
344 "Wrong number of arguments to projection function.\n\
345Expected zero or one arguments.");
346
347 new_string_variable("DODS_Date", dds, (argc == 1) ? argv[0] : 0);
348
349 // Add the selection function to the CE
350
351 ce.append_clause(sel_dods_date, 0); // 0 == no BaseType args
352}
353
354/************************ DODS_Time functions *************************/
355
356
357static void sel_dods_time(int argc, BaseType *[], DDS & dds, bool *result)
358{
359 if (argc != 0)
360 throw Error(malformed_expr,
361 "Wrong number of arguments to internal selection function.\n\
362Please report this error.");
363
364 DODS_Time current =
365 get_instance < DODS_Time, DODS_Time_Factory > (dds);
366
367 // Stuff the "hh:mm:ss" string into `DODS_Time'
368 Str *dods_time = (Str *) dds.var("DODS_Time");
369 string s = current.get().c_str();
370 dods_time->val2buf(&s);
371
372 *result = true;
373}
374
375static void
376proj_dods_time(int argc, BaseType * argv[], DDS & dds,
377 ConstraintEvaluator & ce)
378{
379 if (argc < 0 || argc > 1)
380 throw Error(malformed_expr,
381 "Wrong number of arguments to projection function.\n\
382Expected zero or one arguments.");
383
384 // Create the new variable
385
386 new_string_variable("DODS_Time", dds, (argc == 1) ? argv[0] : 0);
387
388 // Add the selection function to the CE
389
390 ce.append_clause(sel_dods_time, 0); // 0 == no BaseType args
391}
392
393/*************************** Date/Time functions *************************/
394
395// This function is added to the selection part of the CE when the matching
396// `projection function' is run.
397
398static void sel_dods_date_time(int argc, BaseType *[], DDS & dds, bool *result)
399{
400 if (argc != 0)
401 throw Error(malformed_expr,
402 "Wrong number of arguments to internal selection function.\n\
403Please report this error.");
404
405 DODS_Date_Time current
406 = get_instance < DODS_Date_Time, DODS_Date_Time_Factory > (dds);
407
408 Str *dods_date_time = (Str *) dds.var("DODS_Date_Time");
409 string s = current.get().c_str();
410 dods_date_time->val2buf(&s);
411
412 *result = true;
413}
414
415// A projection function: This adds a new variable to the DDS and arranges
416// for the matching selection function (above) to be called.
417
418static void
419proj_dods_date_time(int argc, BaseType * argv[], DDS & dds,
420 ConstraintEvaluator & ce)
421{
422 if (argc < 0 || argc > 1)
423 throw Error(malformed_expr,
424 "Wrong number of arguments to projection function.\n\
425Expected zero or one arguments.");
426
427 // Create the new variable
428
429 new_string_variable("DODS_Date_Time", dds, (argc == 1) ? argv[0] : 0);
430
431 // Add the selection function to the CE
432
433 ce.append_clause(sel_dods_date_time, 0); // 0 == no BaseType args
434}
435
436/*************************** Decimal/Year functions *************************/
437
438// This function is added to the selection part of the CE when the matching
439// `projection function' is run.
440
441static void sel_dods_decimal_year(int argc, BaseType *[], DDS & dds, bool *result)
442{
443 if (argc != 0)
444 throw Error(malformed_expr,
445 "Wrong number of arguments to internal selection function.\n\
446Please report this error.");
447
448 DODS_Date_Time current
449 = get_instance < DODS_Date_Time, DODS_Date_Time_Factory > (dds);
450
451 // Stuff the yyyy/ddd string into DODS_JDate.
452 Str *dods_decimal_year = (Str *) dds.var("DODS_Decimal_Year");
453 string s = current.get(decimal);
454 dods_decimal_year->val2buf(&s);
455
456 *result = true;
457}
458
459// A projection function: This adds a new variable to the DDS and arranges
460// for the matching selection function (above) to be called.
461
462static void
463proj_dods_decimal_year(int argc, BaseType * argv[], DDS & dds,
464 ConstraintEvaluator & ce)
465{
466 if (argc < 0 || argc > 1)
467 throw Error(malformed_expr,
468 "Wrong number of arguments to projection function.\n\
469Expected zero or one arguments.");
470
471 // Create the new variable
472
473 new_string_variable("DODS_Decimal_Year", dds,
474 (argc == 1) ? argv[0] : 0);
475
476 // Add the selection function to the CE
477
478 ce.append_clause(sel_dods_decimal_year, 0); // 0 == no BaseType args
479}
480
481/*************************** Decimal/Year functions *************************/
482
483// This function is added to the selection part of the CE when the matching
484// `projection function' is run.
485
486static void sel_dods_startdecimal_year(int argc, BaseType *[], DDS & dds, bool *result)
487{
488 if (argc != 0)
489 throw Error(malformed_expr,
490 "Wrong number of arguments to internal selection function.\n\
491Please report this error.");
492
493 DODS_Date_Time current
494 =
495 get_instance < DODS_Date_Time, DODS_StartDate_Time_Factory > (dds);
496
497 // Stuff the yyyy/ddd string into DODS_JDate.
498 Str *dods_decimal_year = (Str *) dds.var("DODS_StartDecimal_Year");
499 string s = current.get(decimal);
500 dods_decimal_year->val2buf(&s);
501
502 *result = true;
503}
504
505// A projection function: This adds a new variable to the DDS and arranges
506// for the matching selection function (above) to be called.
507
508static void
509proj_dods_startdecimal_year(int argc, BaseType * argv[], DDS & dds,
510 ConstraintEvaluator & ce)
511{
512 if (argc < 0 || argc > 1)
513 throw Error(malformed_expr,
514 "Wrong number of arguments to projection function.\n\
515Expected zero or one arguments.");
516
517 // Create the new variable
518
519 new_string_variable("DODS_StartDecimal_Year", dds,
520 (argc == 1) ? argv[0] : 0);
521
522 // Add the selection function to the CE
523
524 ce.append_clause(sel_dods_startdecimal_year, 0); // 0 == no BaseType args
525}
526
527/*************************** Decimal/Year functions *************************/
528
529// This function is added to the selection part of the CE when the matching
530// `projection function' is run.
531
532static void sel_dods_enddecimal_year(int argc, BaseType *[], DDS & dds, bool *result)
533{
534 if (argc != 0)
535 throw Error(malformed_expr,
536 "Wrong number of arguments to internal selection function.\n\
537Please report this error.");
538
539 DODS_Date_Time current
540 = get_instance < DODS_Date_Time, DODS_EndDate_Time_Factory > (dds);
541
542 // Stuff the yyyy/ddd string into DODS_JDate.
543 Str *dods_decimal_year = (Str *) dds.var("DODS_EndDecimal_Year");
544 string s = current.get(decimal);
545 dods_decimal_year->val2buf(&s);
546
547 *result = true;
548}
549
550// A projection function: This adds a new variable to the DDS and arranges
551// for the matching selection function (above) to be called.
552
553static void
554proj_dods_enddecimal_year(int argc, BaseType * argv[], DDS & dds,
555 ConstraintEvaluator & ce)
556{
557 if (argc < 0 || argc > 1)
558 throw Error(malformed_expr,
559 "Wrong number of arguments to projection function.\n\
560Expected zero or one arguments.");
561
562 // Create the new variable
563
564 new_string_variable("DODS_EndDecimal_Year", dds,
565 (argc == 1) ? argv[0] : 0);
566
567 // Add the selection function to the CE
568
569 ce.append_clause(sel_dods_enddecimal_year, 0); // 0 == no BaseType args
570}
571
572/************************ DODS_StartDate functions *************************/
573
574static void sel_dods_startdate(int argc, BaseType *[], DDS & dds, bool *result)
575{
576 if (argc != 0)
577 throw Error(malformed_expr,
578 "Wrong number of arguments to internal selection function.\n\
579Please report this error.");
580
581 DODS_Date current =
582 get_instance < DODS_Date, DODS_StartDate_Factory > (dds);
583
584 // Stuff the yyyy/ddd string into DODS_StartDate.
585 Str *dods_date = (Str *) dds.var("DODS_StartDate");
586 // Calling the regular form of DODS_Date::get() returns the data in y/m/d
587 // format. 5/27/99 jhrg
588 string s = current.get().c_str();
589 dods_date->val2buf(&s);
590
591 *result = true;
592}
593
594static void
595proj_dods_startdate(int argc, BaseType * argv[], DDS & dds,
596 ConstraintEvaluator & ce)
597{
598 if (argc < 0 || argc > 1)
599 throw Error(malformed_expr,
600 "Wrong number of arguments to projection function.\n\
601Expected zero or one arguments.");
602
603 new_string_variable("DODS_StartDate", dds, (argc == 1) ? argv[0] : 0);
604
605 // Add the selection function to the CE
606
607 ce.append_clause(sel_dods_startdate, 0); // 0 == no BaseType args
608}
609
610/************************ DODS_StartTime functions *************************/
611
612static void sel_dods_starttime(int argc, BaseType *[], DDS & dds, bool *result)
613{
614 if (argc != 0)
615 throw Error(malformed_expr,
616 "Wrong number of arguments to internal selection function.\n\
617Please report this error.");
618
619 DODS_Time current =
620 get_instance < DODS_Time, DODS_StartTime_Factory > (dds);
621
622 // Stuff the "hh:mm:ss" string into `DODS_Time'
623 Str *dods_time = (Str *) dds.var("DODS_StartTime");
624 string s = current.get().c_str();
625 dods_time->val2buf(&s);
626
627 *result = true;
628}
629
630static void
631proj_dods_starttime(int argc, BaseType * argv[], DDS & dds,
632 ConstraintEvaluator & ce)
633{
634 if (argc < 0 || argc > 1)
635 throw Error(malformed_expr,
636 "Wrong number of arguments to projection function.\n\
637Expected zero or one arguments.");
638
639 // Create the new variable
640
641 new_string_variable("DODS_StartTime", dds, (argc == 1) ? argv[0] : 0);
642
643 // Add the selection function to the CE
644
645 ce.append_clause(sel_dods_starttime, 0); // 0 == no BaseType args
646}
647
648/*************************** StartDate/Time functions *************************/
649
650// This function is added to the selection part of the CE when the matching
651// `projection function' is run.
652
653static void sel_dods_startdate_time(int argc, BaseType *[], DDS & dds, bool *result)
654{
655 if (argc != 0)
656 throw Error(malformed_expr,
657 "Wrong number of arguments to internal selection function.\n\
658Please report this error.");
659
660 DODS_Date_Time current
661 =
662 get_instance < DODS_Date_Time, DODS_StartDate_Time_Factory > (dds);
663
664 Str *dods_date_time = (Str *) dds.var("DODS_StartDate_Time");
665 string s = current.get().c_str();
666 dods_date_time->val2buf(&s);
667
668 *result = true;
669}
670
671// A projection function: This adds a new variable to the DDS and arranges
672// for the matching selection function (above) to be called.
673
674static void
675proj_dods_startdate_time(int argc, BaseType * argv[], DDS & dds,
676 ConstraintEvaluator & ce)
677{
678 if (argc < 0 || argc > 1)
679 throw Error(malformed_expr,
680 "Wrong number of arguments to projection function.\n\
681Expected zero or one arguments.");
682
683 // Create the new variable
684
685 new_string_variable("DODS_StartDate_Time", dds,
686 (argc == 1) ? argv[0] : 0);
687
688 // Add the selection function to the CE
689
690 ce.append_clause(sel_dods_startdate_time, 0); // 0 == no BaseType args
691}
692
693/************************ DODS_EndDate functions *************************/
694
695static void sel_dods_enddate(int argc, BaseType *[], DDS & dds, bool *result)
696{
697 if (argc != 0)
698 throw Error(malformed_expr,
699 "Wrong number of arguments to internal selection function.\n\
700Please report this error.");
701
702 DODS_Date current =
703 get_instance < DODS_Date, DODS_EndDate_Factory > (dds);
704
705 // Stuff the yyyy/ddd string into DODS_EndDate.
706 Str *dods_date = (Str *) dds.var("DODS_EndDate");
707 // Calling the regular form of DODS_Date::get() returns the data in y/m/d
708 // format. 5/27/99 jhrg
709 string s = current.get().c_str();
710 dods_date->val2buf(&s);
711
712 *result = true;
713}
714
715static void
716proj_dods_enddate(int argc, BaseType * argv[], DDS & dds,
717 ConstraintEvaluator & ce)
718{
719 if (argc < 0 || argc > 1)
720 throw Error(malformed_expr,
721 "Wrong number of arguments to projection function.\n\
722Expected zero or one arguments.");
723
724 new_string_variable("DODS_EndDate", dds, (argc == 1) ? argv[0] : 0);
725
726 // Add the selection function to the CE
727
728 ce.append_clause(sel_dods_enddate, 0); // 0 == no BaseType args
729}
730
731/************************ DODS_EndTime functions *************************/
732
733static void sel_dods_endtime(int argc, BaseType *[], DDS & dds, bool *result)
734{
735 if (argc != 0)
736 throw Error(malformed_expr,
737 "Wrong number of arguments to internal selection function.\n\
738Please report this error.");
739
740 DODS_Time current =
741 get_instance < DODS_Time, DODS_EndTime_Factory > (dds);
742
743 // Stuff the "hh:mm:ss" string into `DODS_Time'
744 Str *dods_time = (Str *) dds.var("DODS_EndTime");
745 string s = current.get().c_str();
746 dods_time->val2buf(&s);
747
748 *result = true;
749}
750
751static void
752proj_dods_endtime(int argc, BaseType * argv[], DDS & dds,
753 ConstraintEvaluator & ce)
754{
755 if (argc < 0 || argc > 1)
756 throw Error(malformed_expr,
757 "Wrong number of arguments to projection function.\n\
758Expected zero or one arguments.");
759
760 // Create the new variable
761
762 new_string_variable("DODS_EndTime", dds, (argc == 1) ? argv[0] : 0);
763
764 // Add the selection function to the CE
765
766 ce.append_clause(sel_dods_endtime, 0); // 0 == no BaseType args
767}
768
769/*************************** EndDate/Time functions *************************/
770
771// This function is added to the selection part of the CE when the matching
772// `projection function' is run.
773
774static void sel_dods_enddate_time(int argc, BaseType *[], DDS & dds, bool *result)
775{
776 if (argc != 0)
777 throw Error(malformed_expr,
778 "Wrong number of arguments to internal selection function.\n\
779Please report this error.");
780
781 DODS_Date_Time current
782 = get_instance < DODS_Date_Time, DODS_EndDate_Time_Factory > (dds);
783
784 Str *dods_date_time = (Str *) dds.var("DODS_EndDate_Time");
785 string s = current.get().c_str();
786 dods_date_time->val2buf(&s);
787
788 *result = true;
789}
790
791// A projection function: This adds a new variable to the DDS and arranges
792// for the matching selection function (above) to be called.
793
794static void
795proj_dods_enddate_time(int argc, BaseType * argv[], DDS & dds,
796 ConstraintEvaluator & ce)
797{
798 if (argc < 0 || argc > 1)
799 throw Error(malformed_expr,
800 "Wrong number of arguments to projection function.\n\
801Expected zero or one arguments.");
802
803 // Create the new variable
804
805 new_string_variable("DODS_EndDate_Time", dds,
806 (argc == 1) ? argv[0] : 0);
807
808 // Add the selection function to the CE
809
810 ce.append_clause(sel_dods_enddate_time, 0); // 0 == no BaseType args
811}
812
813void ff_register_functions()
814{
815 libdap::ServerFunction *ff_dap_function;
816
817 // The first set of functions all are 'Selection functions.' They are used
818 // in the selection part of a CE to choose which instances of a sequence
819 // will be sent. Each of these particular functions compare a given date,
820 // or range of dates, to the date information in the sequence instance.
821 // These function are very specific to sequences that contain date/time
822 // information.
823
824 ff_dap_function = new libdap::ServerFunction(
825 // The name of the function as it will appear in a constraint expression
826 "date",
827 // The version of the function
828 "1.0",
829 // A brief description of the function
830 string("Compares the current variable to the date parameters. If only one parameter is passed then ") +
831 "this returns true if they're the same date. If two parameters are passed they are considered to be the beginning "+
832 "and end of a date range and the function returns true if the current variable falls in the range.",
833 // A usage/syntax statement
834 "date(date_1[, date_2])",
835 // A URL that points two a web page describing the function
836 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
837 // A URI that defines the role of the function
838 "https://services.opendap.org/dap4/freeform-function/date",
839 // A pointer to the helloWorld() function
840 func_date
841 );
842 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
843
844 ff_dap_function = new libdap::ServerFunction(
845 "date_range",
846 "1.0",
847 string("Compares the current sequence instance with the passed date range. Return true if the instance is within the range. ")+
848 "If only single date parameter is used as a start date to now.",
849 "date_range(startDate, endDate)",
850 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
851 "https://services.opendap.org/dap4/freeform-function/date_range",
852 func_date_range
853 );
854 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
855
856 ff_dap_function = new libdap::ServerFunction(
857 "start_date",
858 "1.0",
859 string("The current sequence instance is compared, as a start date, to the single passed parameter. Returns true if they're the same date. ")+
860 "If two parameters are passed they are considered a date range. True is returned if the current variable falls into the range.",
861 "start_date(date[, endDate])",
862 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
863 "https://services.opendap.org/dap4/freeform-function/start_date",
864 func_startdate
865 );
866 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
867
868 ff_dap_function = new libdap::ServerFunction(
869 "end_date",
870 "1.0",
871 string("The current sequence instance is compared, as an end date, to the single passed parameter. Returns true if they're the same date. ") +
872 "If two parameters are passed they are considered a date range. True is returned if the current variable falls into the range.",
873 "end_date(date[, endDate])",
874 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
875 "https://services.opendap.org/dap4/freeform-function/end_date",
876 func_enddate
877 );
878 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
879
880 ff_dap_function = new libdap::ServerFunction(
881 "time",
882 "1.0",
883 "Compares the current variable with the passed time range. Return true if the sequence instance is within the range.",
884 "time( time[, endTime] )",
885 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
886 "https://services.opendap.org/dap4/freeform-function/time",
887 func_time
888 );
889 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
890
891 ff_dap_function = new libdap::ServerFunction(
892 "start_time",
893 "1.0",
894 "Compares the current variable with the passed time range. Return true if the sequence instance is within the range.",
895 "start_time( time[, endTime] )",
896 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
897 "https://services.opendap.org/dap4/freeform-function/start_time",
898 func_starttime
899 );
900 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
901
902 ff_dap_function = new libdap::ServerFunction(
903 "end_time",
904 "1.0",
905 "Compares the current variable with the passed time range. Return true if the sequence instance is within the range.",
906 "end_time( time[, endTime] )",
907 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
908 "https://services.opendap.org/dap4/freeform-function/end_time",
909 func_endtime
910 );
911 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
912
913 ff_dap_function = new libdap::ServerFunction(
914 "date_time",
915 "1.0",
916 "Compares the current sequence instance with the passed date/time range. Return true if the instance is within the range.",
917 "date_time( date/time [, end date/time] )",
918 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
919 "https://services.opendap.org/dap4/freeform-function/date_time",
920 func_date_time
921 );
922 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
923
924 ff_dap_function = new libdap::ServerFunction(
925 "start_date_time",
926 "1.0",
927 "Compares the current sequence instance with the passed date/time range. Return true if the instance is within the range.",
928 "start_date_time( date/time [, end date/time] )",
929 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
930 "https://services.opendap.org/dap4/freeform-function/start_date_time",
931 func_startdate_time
932 );
933 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
934
935 ff_dap_function = new libdap::ServerFunction(
936 "end_date_time",
937 "1.0",
938 "Compares the current sequence instance with the passed date/time range. Return true if the instance is within the range.",
939 "end_date_time(date/time [, end date/time] )",
940 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
941 "https://services.opendap.org/dap4/freeform-function/end_date_time",
942 func_enddate_time
943 );
944 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
945
946 // These are 'Projection Functions' that add new variables to a dataset.
947 // Their operation might be superceeded by NCML (except that NCML doesn't
948 // do exactly what they do, but it could be extended...). The function
949 // is used in the projection part of a URL.
950
951 ff_dap_function = new libdap::ServerFunction(
952 "DODS_Time",
953 "1.0",
954 "Adds a variable named DODS_Time that is an ISO 8601 time string to the dataset.",
955 "DODS_Time( [Sequence or Structure] )",
956 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
957 "https://services.opendap.org/dap4/freeform-function/DODS_Time",
958 proj_dods_time
959 );
960 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
961
962 ff_dap_function = new libdap::ServerFunction(
963 "DODS_StartTime",
964 "1.0",
965 "Adds a variable named DODS_StartTime that is an ISO 8601 time string to the dataset.",
966 "DODS_StartTime( [Sequence or Structure] )",
967 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
968 "https://services.opendap.org/dap4/freeform-function/DODS_StartTime",
969 proj_dods_starttime
970 );
971 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
972
973 ff_dap_function = new libdap::ServerFunction(
974 "DODS_EndTime",
975 "1.0",
976 "Adds a variable named DODS_EndTime that is an ISO 8601 time string to the dataset.",
977 "DODS_EndTime( [Sequence or Structure] )",
978 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
979 "https://services.opendap.org/dap4/freeform-function/DODS_EndTime",
980 proj_dods_endtime
981 );
982 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
983
984 ff_dap_function = new libdap::ServerFunction(
985 "DODS_JDate",
986 "1.0",
987 "Adds a variable named DODS_JDate that is the Julian day number to the dataset.",
988 "DODS_JDate( [Sequence or Structure variable] )",
989 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
990 "https://services.opendap.org/dap4/freeform-function/DODS_JDATE",
991 proj_dods_jdate
992 );
993 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
994
995 ff_dap_function = new libdap::ServerFunction(
996 "DODS_Date",
997 "1.0",
998 string("Adds a variable named DODS_Date that is an ISO 8601 date string to the dataset."),
999 "DODS_Date( [Sequence or Structure] )",
1000 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1001 "https://services.opendap.org/dap4/freeform-function/DODS_Date",
1002 proj_dods_date
1003 );
1004 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1005
1006 ff_dap_function = new libdap::ServerFunction(
1007 "DODS_StartDate",
1008 "1.0",
1009 string("Adds a variable named DODS_StartDate that is an ISO 8601 date string to the dataset."),
1010 "DODS_StartDate( [Sequence or Structure] )",
1011 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1012 "https://services.opendap.org/dap4/freeform-function/DODS_StartDate",
1013 proj_dods_startdate
1014 );
1015 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1016
1017 ff_dap_function = new libdap::ServerFunction(
1018 "DODS_EndDate",
1019 "1.0",
1020 string("Adds a variable named DODS_EndDate that is an ISO 8601 date string to the dataset."),
1021 "DODS_EndDate( [Sequence or Structure] )",
1022 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1023 "https://services.opendap.org/dap4/freeform-function/DODS_EndDate",
1024 proj_dods_enddate
1025 );
1026 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1027 ff_dap_function = new libdap::ServerFunction(
1028 "DODS_Date_Time",
1029 "1.0",
1030 "Adds a variable named DODS_Date_Time that is an ISO 8601 date/time string to the dataset.",
1031 "DODS_Date_Time( [Sequence or Structure] )",
1032 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1033 "https://services.opendap.org/dap4/freeform-function/DODS_Date_Time",
1034 proj_dods_date_time
1035 );
1036 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1037
1038 ff_dap_function = new libdap::ServerFunction(
1039 "DODS_StartDate_Time",
1040 "1.0",
1041 "Adds a variable named DODS_StartDate_Time that is an ISO 8601 date/time string to the dataset.",
1042 "DODS_StartDate_Time( [Sequence or Structure] )",
1043 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1044 "https://services.opendap.org/dap4/freeform-function/DODS_StartDate_Time",
1045 proj_dods_startdate_time
1046 );
1047 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1048
1049 ff_dap_function = new libdap::ServerFunction(
1050 "DODS_EndDate_Time",
1051 "1.0",
1052 "Adds a variable named DODS_EndDate_Time that is an ISO 8601 date/time string to the dataset.",
1053 "DODS_EndDate_Time( [Sequence or Structure] )",
1054 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1055 "https://services.opendap.org/dap4/freeform-function/DODS_EndDate_Time",
1056 proj_dods_enddate_time
1057 );
1058 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1059
1060 ff_dap_function = new libdap::ServerFunction(
1061 "DODS_Decimal_Year",
1062 "1.0",
1063 "Adds a variable named DODS_Decimal_Year that is date as a decimal year/day value string to the dataset.",
1064 "DODS_Decimal_Year( [Sequence or Structure] )",
1065 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1066 "https://services.opendap.org/dap4/freeform-function/DODS_Decimal_Year",
1067 proj_dods_decimal_year
1068 );
1069 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1070
1071 ff_dap_function = new libdap::ServerFunction(
1072 "DODS_StartDecimal_Year",
1073 "1.0",
1074 "Adds a variable named DODS_StartDecimal_Year that is date as a decimal year/day value string to the dataset.",
1075 "DODS_StartDecimal_Year( [Sequence or Structure] )",
1076 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1077 "https://services.opendap.org/dap4/freeform-function/DODS_StartDecimal_Year",
1078 proj_dods_startdecimal_year
1079 );
1080 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1081
1082 ff_dap_function = new libdap::ServerFunction(
1083 "DODS_EndDecimal_Year",
1084 "1.0",
1085 "Adds a variable named DODS_EndDecimal_Year that is date as a decimal year/day value string to the dataset.",
1086 "DODS_EndDecimal_Year( [Sequence or Structure] )",
1087 "https://docs.opendap.org/index.php/Server_Side_Processing_Functions#FreeForm_Functions",
1088 "https://services.opendap.org/dap4/freeform-function/DODS_EndDecimal_Year",
1089 proj_dods_enddecimal_year
1090 );
1091 libdap::ServerFunctionsList::TheList()->add_function(ff_dap_function);
1092}
string get(date_format format=ymd, bool gmt=true) const
string get(date_format format=ymd) const
Definition DODS_Date.cc:429
string get(bool gmt=true) const
Definition DODS_Time.cc:294
Definition FFStr.h:47