2 ======================================================================
4 CREATOR: eric 03 April 1999
8 $Id: storage.c,v 1.6 2008-01-02 20:07:46 dothebart Exp $
11 (C) COPYRIGHT 1999 Eric Busboom
12 http://www.softwarestudio.org
14 The contents of this file are subject to the Mozilla Public License
15 Version 1.0 (the "License"); you may not use this file except in
16 compliance with the License. You may obtain a copy of the License at
17 http://www.mozilla.org/MPL/
19 Software distributed under the License is distributed on an "AS IS"
20 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
21 the License for the specific language governing rights and
22 limitations under the License.
24 The original author is Eric Busboom
25 The original code is usecases.c
28 ======================================================================*/
30 #include <libical/ical.h>
32 #include <string.h> /* for strdup */
33 #include <stdlib.h> /* for malloc */
34 #include <stdio.h> /* for printf */
35 #include <time.h> /* for time() */
36 #include "icalmemory.h"
37 #include "icaldirset.h"
38 #include "icalfileset.h"
40 #include "icalbdbset.h"
42 #include "icalerror.h"
43 #include "icalrestriction.h"
44 #include "icalcalendar.h"
46 #define OUTPUT_FILE "filesetout.ics"
47 #define DATABASE "calendar.db"
49 /* define sample calendar struct */
55 int total_size_offset;
56 int vcalendar_size_offset;
58 int title_size_offset;
70 int vcalendar_init(struct calendar **cal, char *vcalendar, char *title);
73 int get_title(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
74 char * parse_vcalendar(const DBT *dbt) ;
77 char * pack_calendar(struct calendar *cal, int size);
78 struct calendar * unpack_calendar(char *str, int size);
80 char str[] = "BEGIN:VCALENDAR\n\
81 PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\
86 DTSTART:19981025T020000\n\
87 RDATE:19981025T020000\n\
93 DTSTART:19990404T020000\n\
94 RDATE:19990404T020000\n\
101 DTSTAMP:19980309T231000Z\n\
102 UID:guid-1.host1.com\n\
103 ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\
104 ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\
105 DESCRIPTION:Project XYZ Review Meeting\n\
106 CATEGORIES:MEETING\n\
108 CREATED:19980309T130000Z\n\
109 SUMMARY:XYZ Project Review\n\
110 DTSTART;TZID=US-Eastern:19980312T083000\n\
111 DTEND;TZID=US-Eastern:19980312T093000\n\
112 LOCATION:1CP Conference Room 4350\n\
115 DTSTAMP:19980309T231000Z\n\
117 DTSTOMP:19980309T231000Z\n\
118 UID:guid-1.host1.com\n\
122 char str2[] = "BEGIN:VCALENDAR\n\
123 PRODID:\"-//RDU Software//NONSGML HandCal//EN\"\n\
126 DTSTAMP:19980309T231000Z\n\
127 UID:guid-1.host1.com\n\
128 ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com\n\
129 ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:MAILTO:employee-A@host.com\n\
130 DESCRIPTION:Project XYZ Review Meeting\n\
131 CATEGORIES:MEETING\n\
133 CREATED:19980309T130000Z\n\
134 SUMMARY:XYZ Project Review\n\
135 DTSTART;TZID=US-Eastern:19980312T083000\n\
136 DTEND;TZID=US-Eastern:19980312T093000\n\
137 LOCATION:1CP Conference Room 4350\n\
147 struct icaltimetype start, end;
148 icalcomponent *c,*clone, *itr;
150 start = icaltime_from_timet( time(0),0);
154 cout = icalfileset_new(OUTPUT_FILE);
157 c = icalparser_parse_string(str2);
160 /* Add data to the file */
162 for(month = 1; month < 10; month++){
163 icalcomponent *event;
164 icalproperty *dtstart, *dtend;
166 cout = icalfileset_new(OUTPUT_FILE);
172 clone = icalcomponent_new_clone(c);
174 event = icalcomponent_get_first_component(clone,ICAL_VEVENT_COMPONENT);
177 dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
179 icalproperty_set_dtstart(dtstart,start);
181 dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
183 icalproperty_set_dtend(dtend,end);
185 icalfileset_add_component(cout,clone);
186 icalfileset_commit(cout);
194 cout = icalfileset_new(OUTPUT_FILE);
197 for (itr = icalfileset_get_first_component(cout);
199 itr = icalfileset_get_next_component(cout)){
201 icalcomponent *event;
202 icalproperty *dtstart, *dtend;
206 event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
208 dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
209 dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
211 printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
212 icalproperty_as_ical_string(dtend));
216 /* Remove all of them */
220 cout = icalfileset_new(OUTPUT_FILE);
223 for (itr = icalfileset_get_first_component(cout);
225 itr = icalfileset_get_next_component(cout)){
228 icalfileset_remove_component(cout, itr);
234 /* Print them out again */
236 cout = icalfileset_new(OUTPUT_FILE);
240 for (itr = icalfileset_get_first_component(cout);
242 itr = icalfileset_get_next_component(cout)){
244 icalcomponent *event;
245 icalproperty *dtstart, *dtend;
249 event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
251 dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
252 dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
254 printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
255 icalproperty_as_ical_string(dtend));
265 In this example, we're storing a calendar with several components
266 under the reference id "calendar_7286" and retrieving records based
267 on title, "month_1" through "month_10". We use a number of the
268 "optional" arguments to specify secondary indices, sub-databases
269 (i.e. having multiple databases residing within a single Berkeley
270 DB file), and keys for storage and retrieval.
279 int num_components=0;
282 char *subdb, *szdata, *szpacked_data;
284 struct icaltimetype start, end;
285 icalcomponent *c,*clone, *itr;
290 struct calendar *cal;
293 start = icaltime_from_timet( time(0),0);
297 /* Note: as per the Berkeley DB ref pages:
299 * The database argument is optional, and allows applications to
300 * have multiple databases in a single file. Although no database
301 * argument needs to be specified, it is an error to attempt to
302 * open a second database in a file that was not initially created
303 * using a database name.
307 subdb = "calendar_id";
310 /* open database, using subdb */
311 dbp = icalbdbset_database_open(DATABASE, subdb, DB_HASH);
312 sdbp = icalbdbset_secondary_open(dbp,
318 c = icalparser_parse_string(str2);
321 /* Add data to the file */
323 for(month = 1; month < 10; month++){
324 icalcomponent *event;
325 icalproperty *dtstart, *dtend, *location;
328 cout = icalbdbset_new(dbp, sdbp, NULL);
334 clone = icalcomponent_new_clone(c);
336 event = icalcomponent_get_first_component(clone,
337 ICAL_VEVENT_COMPONENT);
340 dtstart = icalcomponent_get_first_property(event,
341 ICAL_DTSTART_PROPERTY);
343 icalproperty_set_dtstart(dtstart,start);
345 dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
347 icalproperty_set_dtend(dtend,end);
349 location = icalcomponent_get_first_property(event, ICAL_LOCATION_PROPERTY);
353 /* change the uid to include the month */
354 sprintf(uid, "%s_%d", icalcomponent_get_uid(clone), month);
355 icalcomponent_set_uid(clone, uid);
358 icalbdbset_add_component(cout,clone);
361 icalbdbset_commit(cout);
363 num_components = icalcomponent_count_components(clone, ICAL_ANY_COMPONENT);
369 /* try out the cursor operations */
370 memset(&key, 0, sizeof(DBT));
371 memset(&data, 0, sizeof(DBT));
373 ret = icalbdbset_acquire_cursor(dbp, &dbcp);
374 ret = icalbdbset_get_first(dbcp, &key, &data);
375 ret = icalbdbset_get_next(dbcp, &key, &data);
376 ret = icalbdbset_get_last(dbcp, &key, &data);
380 for(month = 1, count=0; month < 10; month++){
383 icalcomponent *event;
384 icalproperty *dtstart, *dtend;
386 cout = icalbdbset_new(dbp, sdbp, NULL);
389 for (itr = icalbdbset_get_first_component(cout);
391 itr = icalbdbset_get_next_component(cout)){
393 icalcomponent *event;
394 icalproperty *dtstart, *dtend;
398 event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
400 dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
401 dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
403 printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
404 icalproperty_as_ical_string(dtend));
411 icalbdbset_database_close(dbp);
412 icalbdbset_database_close(sdbp);
415 dbp = icalbdbset_database_open(DATABASE, subdb, DB_HASH);
416 sdbp = icalbdbset_secondary_open(dbp,
422 /* Remove all of them */
423 for(month = 1; month < 10; month++){
425 cout = icalbdbset_new(dbp, sdbp, NULL);
428 for (itr = icalbdbset_get_first_component(cout);
430 itr = icalbdbset_get_next_component(cout)){
432 icalbdbset_remove_component(cout, itr);
435 icalbdbset_commit(cout);
440 /* Print them out again */
442 for(month = 1, count=0; month < 10; month++){
445 icalcomponent *event;
446 icalproperty *dtstart, *dtend;
448 cout = icalbdbset_new(dbp, sdbp, NULL);
451 for (itr = icalbdbset_get_first_component(cout);
453 itr = icalbdbset_get_next_component(cout)){
455 icalcomponent *event;
456 icalproperty *dtstart, *dtend;
460 event = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
462 dtstart = icalcomponent_get_first_property(event,ICAL_DTSTART_PROPERTY);
463 dtend = icalcomponent_get_first_property(event,ICAL_DTEND_PROPERTY);
465 printf("%d %s %s\n",count, icalproperty_as_ical_string(dtstart),
466 icalproperty_as_ical_string(dtend));
473 /* get_title -- extracts a secondary key (the vcalendar)
474 * from a primary key/data pair */
476 /* just create a random title for now */
478 int get_title(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey)
483 memset(skey, 0, sizeof(DBT));
485 cl = icalparser_parse_string((char *)pdata->data);
486 sprintf(title, "title_%s", icalcomponent_get_uid(cl));
488 skey->data = strdup(title);
489 skey->size = strlen(skey->data);
493 char * parse_vcalendar(const DBT *dbt)
496 struct calendar *cal;
498 str = (char *)dbt->data;
499 cal = unpack_calendar(str, dbt->size);
501 return cal->vcalendar;
507 int vcalendar_init(struct calendar **rcal, char *vcalendar, char *title)
509 int vcalendar_size, title_size, total_size;
510 struct calendar *cal;
513 vcalendar_size = strlen(vcalendar);
516 vcalendar_size = strlen(vcalendar);
520 title_size = strlen(title);
523 title_size = strlen(title);
526 total_size = sizeof(struct calendar) + vcalendar_size + title_size;
528 if((cal = (struct calendar *)malloc(total_size))==NULL)
530 memset(cal, 0, total_size);
533 cal->total_size_offset = sizeof(int);
534 cal->vcalendar_size_offset = (sizeof(int) * 7);
535 cal->vcalendar_offset = cal->vcalendar_size_offset + sizeof(int);
536 cal->title_size_offset = cal->vcalendar_offset + vcalendar_size;
537 cal->title_offset = cal->title_size_offset + sizeof(int);
540 cal->total_size = total_size;
541 cal->vcalendar_size = vcalendar_size;
542 cal->title_size = title_size;
544 if (vcalendar && *vcalendar)
545 cal->vcalendar = strdup(vcalendar);
548 cal->title = strdup(title);
555 char * pack_calendar(struct calendar *cal, int size)
559 if((str = (char *)malloc(sizeof(char) * size))==NULL)
563 memcpy(str, &cal->ID, sizeof(cal->ID));
566 memcpy(str + cal->total_size_offset,
568 sizeof(cal->total_size));
571 memcpy(str + cal->vcalendar_size_offset,
572 &cal->vcalendar_size,
573 sizeof(cal->vcalendar_size));
576 memcpy(str + cal->vcalendar_offset,
578 cal->vcalendar_size);
581 memcpy(str + cal->title_size_offset,
583 sizeof(cal->title_size));
586 memcpy(str + cal->title_offset,
593 struct calendar * unpack_calendar(char *str, int size)
595 struct calendar *cal;
596 if((cal = (struct calendar *) malloc(size))==NULL)
598 memset(cal, 0, size);
601 cal->total_size_offset = sizeof(int);
602 cal->vcalendar_size_offset = (sizeof(int) * 7);
603 cal->vcalendar_offset = cal->vcalendar_size_offset + sizeof(int);
606 memcpy(&cal->ID, str, sizeof(cal->ID));
609 memcpy(&cal->total_size,
610 str + cal->total_size_offset,
611 sizeof(cal->total_size));
614 memcpy(&cal->vcalendar_size,
615 str + cal->vcalendar_size_offset,
616 sizeof(cal->vcalendar_size));
618 if((cal->vcalendar = (char *)malloc(sizeof(char) *
619 cal->vcalendar_size))==NULL)
623 memcpy(cal->vcalendar,
624 (char *)(str + cal->vcalendar_offset),
625 cal->vcalendar_size);
627 cal->title_size_offset = cal->vcalendar_offset + cal->vcalendar_size;
628 cal->title_offset = cal->title_size_offset + sizeof(int);
631 memcpy(&cal->title_size,
632 str + cal->title_size_offset,
633 sizeof(cal->title_size));
635 if((cal->title = (char *)malloc(sizeof(char) *
636 cal->title_size))==NULL)
641 (char *)(str + cal->title_offset),
650 icalcomponent *c, *gauge;
653 icalfileset* cluster;
654 struct icalperiodtype rtime;
655 icaldirset *s = icaldirset_new("store");
660 rtime.start = icaltime_from_timet( time(0),0);
662 cluster = icalfileset_new(OUTPUT_FILE);
664 assert(cluster != 0);
668 /* Duplicate every component in the cluster NUMCOMP times */
670 icalerror_clear_errno();
672 for (i = 1; i<NUMCOMP+1; i++){
674 /*rtime.start.month = i%12;*/
675 rtime.start.month = i;
676 rtime.end = rtime.start;
679 for (itr = icalfileset_get_first_component(cluster);
681 itr = icalfileset_get_next_component(cluster)){
682 icalcomponent *clone, *inner;
685 inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
690 /* Change the dtstart and dtend times in the component
693 clone = icalcomponent_new_clone(itr);
694 inner = icalcomponent_get_first_component(itr,ICAL_VEVENT_COMPONENT);
696 assert(icalerrno == ICAL_NO_ERROR);
700 p = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY);
701 assert(icalerrno == ICAL_NO_ERROR);
704 p = icalproperty_new_dtstart(rtime.start);
705 icalcomponent_add_property(inner,p);
707 icalproperty_set_dtstart(p,rtime.start);
709 assert(icalerrno == ICAL_NO_ERROR);
712 p = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY);
713 assert(icalerrno == ICAL_NO_ERROR);
716 p = icalproperty_new_dtstart(rtime.end);
717 icalcomponent_add_property(inner,p);
719 icalproperty_set_dtstart(p,rtime.end);
721 assert(icalerrno == ICAL_NO_ERROR);
723 printf("\n----------\n%s\n---------\n",icalcomponent_as_ical_string(inner));
725 error = icaldirset_add_component(s,
726 icalcomponent_new_clone(itr));
728 assert(icalerrno == ICAL_NO_ERROR);
736 ICAL_VCALENDAR_COMPONENT,
738 ICAL_VEVENT_COMPONENT,
739 icalproperty_vanew_summary(
740 "Submit Income Taxes",
741 icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
745 ICAL_VEVENT_COMPONENT,
746 icalproperty_vanew_summary(
747 "Bastille Day Party",
748 icalparameter_new_xliccomparetype(ICAL_XLICCOMPARETYPE_EQUAL),
756 icaldirset_select(s,gauge);
758 for(c = icaldirset_first(s); c != 0; c = icaldirset_next(s)){
760 printf("Got one! (%d)\n", count++);
763 printf("%s", icalcomponent_as_ical_string(c));;
764 if (icaldirset_store(s2,c) == 0){
765 printf("Failed to write!\n");
767 icalcomponent_free(c);
769 printf("Failed to get component\n");
778 for(c = icaldirset_get_first_component(s);
780 c = icaldirset_get_next_component(s)){
783 printf("%s", icalcomponent_as_ical_string(c));;
785 printf("Failed to get component\n");
790 /* Remove all of the components */
792 while((c=icaldirset_get_current_component(s)) != 0 ){
795 icaldirset_remove_component(s,c);
809 icalcalendar* calendar = icalcalendar_new("calendar");
811 struct icaltimetype atime = icaltime_null_time();
813 comp = icalcomponent_vanew(
814 ICAL_VEVENT_COMPONENT,
815 icalproperty_new_version("2.0"),
816 icalproperty_new_description("This is an event"),
817 icalproperty_new_dtstart(atime),
818 icalproperty_vanew_comment(
820 icalparameter_new_cn("A Common Name 1"),
821 icalparameter_new_cn("A Common Name 2"),
822 icalparameter_new_cn("A Common Name 3"),
823 icalparameter_new_cn("A Common Name 4"),
825 icalproperty_vanew_xlicerror(
826 "This is only a test",
827 icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_COMPONENTPARSEERROR),
833 s = icalcalendar_get_booked(calendar);
835 error = icaldirset_add_component(s,comp);
837 assert(error == ICAL_NO_ERROR);
839 c = icalcalendar_get_properties(calendar);
841 error = icalfileset_add_component(c,icalcomponent_new_clone(comp));
843 assert(error == ICAL_NO_ERROR);
845 icalcalendar_free(calendar);
850 int main(int argc, char *argv[])
853 printf("\n------------Test File Set---------------\n");
856 printf("\n------------Test Dir Set---------------\n");
860 printf("\n------------Test BerkeleyDB Set---------------\n");
865 printf("\n------------Test Calendar---------------\n");