]> err.no Git - scalable-opengroupware.org/commitdiff
bugfixes and performance upgrade for recurrent events
authorznek <znek@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 1 Mar 2005 17:08:11 +0000 (17:08 +0000)
committerznek <znek@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 1 Mar 2005 17:08:11 +0000 (17:08 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@617 d1b88da0-ebda-0310-925b-ed51d893ca5b

19 files changed:
OGoContentStore/ChangeLog
OGoContentStore/GNUmakefile
OGoContentStore/OCSiCalFieldExtractor.m
OGoContentStore/OGoContentStore.xcode/project.pbxproj
OGoContentStore/Version
OGoContentStore/appointment.ocs
OGoContentStore/iCalRepeatableEntityObject+OCS.h [new file with mode: 0644]
OGoContentStore/iCalRepeatableEntityObject+OCS.m [new file with mode: 0644]
OGoContentStore/sql/foldertablecreate-helge-privcal.psql
OGoContentStore/sql/foldertablecreate-helge-privcal.sqlite
OGoContentStore/sql/generate-folderinfo-sql-for-users-sqlite.sh
OGoContentStore/sql/generate-folderinfo-sql-for-users.sh
SOGo/SOGo.xcode/project.pbxproj
SOGo/SoObjects/Appointments/ChangeLog
SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m
SOGo/SoObjects/Appointments/Version
SOGo/UI/Scheduler/ChangeLog
SOGo/UI/Scheduler/UIxCalDateLabel.m
SOGo/UI/Scheduler/Version

index 40b29c3bdc4cc6e64d1a0fc6a80ca9c50816b987..0fd38dc95c73bf3616dd8354aca93b0f278efe06 100644 (file)
@@ -1,3 +1,23 @@
+2005-03-01  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * v0.9.22
+
+       * appointment.ocs: added 'cycleenddate' and 'cycleinfo' to address
+         previous performance issues
+
+       * OCSiCalFieldExtractor.m: set 'cycleenddate' and 'cycleinfo' for
+         recurrent events. Reverted setting of 'enddate' to the previous
+         behaviour since 'cycleenddate' is dedicated to the task now
+       
+       * iCalRepeatableEntityObject+OCS.[hm]: new category used by the
+         OCSiCalFieldExtractor to extract cycleInfo in an appropriate format
+
+       * sql/generate-folderinfo-sql-for-users.sh,
+         sql/foldertablecreate-helge-privcal.psql,
+         sql/foldertablecreate-helge-privcal.sqlite,
+         sql/generate-folderinfo-sql-for-users-sqlite.sh: adjusted to new
+         schema
+
 2005-03-01  Helge Hess  <helge.hess@opengroupware.org>
 
        * OCSFolder.m: added support for storing content and quick info in
index d69c35744b39fc70a2cec1e3214edba147e0adb3..2d07b7a1a9b68bdb8b24420b7064fca19afbe936 100644 (file)
@@ -11,35 +11,37 @@ TYPEMODELS_DIR = $(GNUSTEP_USER_ROOT)/Library/OCSTypeModels/
 libOGoContentStore_HEADER_FILES_DIR         = .
 libOGoContentStore_HEADER_FILES_INSTALL_DIR = /OGoContentStore
 
-libOGoContentStore_HEADER_FILES +=     \
-       NSURL+OCS.h                     \
-       EOAdaptorChannel+OCS.h          \
+libOGoContentStore_HEADER_FILES +=             \
+       NSURL+OCS.h                             \
+       EOAdaptorChannel+OCS.h                  \
+       iCalRepeatableEntityObject+OCS.h        \
        \
-       OCSContext.h                    \
-       OCSFieldInfo.h                  \
-       OCSFolder.h                     \
-       OCSFolderManager.h              \
-       OCSFolderType.h                 \
-       OCSChannelManager.h             \
-       OCSFieldExtractor.h             \
-       OCSiCalFieldExtractor.h         \
-       OCSStringFormatter.h            \
-
-libOGoContentStore_OBJC_FILES +=       \
-       NSURL+OCS.m                     \
-       EOAdaptorChannel+OCS.m          \
-       EOQualifier+OCS.m               \
+       OCSContext.h                            \
+       OCSFieldInfo.h                          \
+       OCSFolder.h                             \
+       OCSFolderManager.h                      \
+       OCSFolderType.h                         \
+       OCSChannelManager.h                     \
+       OCSFieldExtractor.h                     \
+       OCSiCalFieldExtractor.h                 \
+       OCSStringFormatter.h                    \
+
+libOGoContentStore_OBJC_FILES +=               \
+       NSURL+OCS.m                             \
+       EOAdaptorChannel+OCS.m                  \
+       EOQualifier+OCS.m                       \
+       iCalRepeatableEntityObject+OCS.m        \
        \
-       OCSContext.m                    \
-       OCSFieldInfo.m                  \
-       OCSFolder.m                     \
-       OCSFolderManager.m              \
-       OCSFolderType.m                 \
-       OCSChannelManager.m             \
-       OCSFieldExtractor.m             \
-       OCSiCalFieldExtractor.m         \
-       OCSContactFieldExtractor.m      \
-       OCSStringFormatter.m            \
+       OCSContext.m                            \
+       OCSFieldInfo.m                          \
+       OCSFolder.m                             \
+       OCSFolderManager.m                      \
+       OCSFolderType.m                         \
+       OCSChannelManager.m                     \
+       OCSFieldExtractor.m                     \
+       OCSiCalFieldExtractor.m                 \
+       OCSContactFieldExtractor.m              \
+       OCSStringFormatter.m                    \
 
 libOGoContentStore_TYPEMODELS += \
        appointment.ocs \
index cefa04ba1d1ce21a215aa272e7f519fbd23f1af9..27ea7dcb91271d85d9eaa36bc40a2ec3f2154e5d 100644 (file)
@@ -23,6 +23,7 @@
 #include "common.h"
 #include <SaxObjC/SaxObjC.h>
 #include <NGiCal/NGiCal.h>
+#include "iCalRepeatableEntityObject+OCS.h"
 
 @implementation OCSiCalFieldExtractor
 
@@ -124,21 +125,20 @@ static NSNumber                  *distantFutureNumber = nil;
   
   if ([startDate isNotNull]) 
     [row setObject:[self numberForDate:startDate] forKey:@"startdate"];
-  if (![_event isRecurrent]) {
-    if ([endDate isNotNull]) 
-      [row setObject:[self numberForDate:endDate] forKey:@"enddate"];
-  }
-  else {
+  if ([endDate isNotNull]) 
+    [row setObject:[self numberForDate:endDate] forKey:@"enddate"];
+
+  if ([_event isRecurrent]) {
     NSCalendarDate *date;
     
     date = [_event lastPossibleRecurrenceStartDate];
     if (!date) {
-      /* date might be nil, indicating an unbound recurrence - we substitute
-         this with a very distant date since 'enddate' is not allowed to be
-         NULL */
+      /* this could also be *nil*, but in the end it makes the fetchspecs
+         more complex - thus we set it to a "reasonable" distant future */
       date = distantFuture;
     }
-    [row setObject:[self numberForDate:date] forKey:@"enddate"];
+    [row setObject:[self numberForDate:date] forKey:@"cycleenddate"];
+    [row setObject:[_event cycleInfo] forKey:@"cycleinfo"];
   }
   if ([participants length] > 0)
     [row setObject:participants forKey:@"participants"];
index 1266e6a7eb565f0f7a8374c1771c17a892238a91..deacbec95e203592eb5a3a90c2fa41e0798286cb 100644 (file)
                AD0CF977071FE18800E72147 = {
                        children = (
                                AD0CF97E071FE18800E72147,
-                               AD0CF97D071FE18800E72147,
-                               AD0CF978071FE18800E72147,
-                               AD0CF979071FE18800E72147,
-                               AD0CF97A071FE18800E72147,
-                               AD0CF97B071FE18800E72147,
-                               AD0CF97C071FE18800E72147,
-                               AD0CF97F071FE18800E72147,
-                               AD0CF980071FE18800E72147,
-                               AD0CF981071FE18800E72147,
-                               AD0CF982071FE18800E72147,
-                               AD0CF983071FE18800E72147,
+                               ADB79C3707D4B7AA00CA782A,
+                               ADB79C3A07D4B7B800CA782A,
                        );
                        isa = PBXGroup;
                        name = SQL;
                                AD0CF960071FE18800E72147,
                                AD0CF952071FE18800E72147,
                                AD0CF954071FE18800E72147,
+                               ADB79C6A07D4B92B00CA782A,
                        );
                        indentWidth = 2;
                        isa = PBXGroup;
                                AD0CF95F071FE18800E72147,
                                AD0CF951071FE18800E72147,
                                AD0CF953071FE18800E72147,
+                               ADB79C6907D4B92B00CA782A,
                        );
                        indentWidth = 2;
                        isa = PBXGroup;
                        refType = 4;
                        sourceTree = "<group>";
                };
+               ADB79C3207D4B7A200CA782A = {
+                       fileEncoding = 5;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       path = "folderinfo-create.sqlite";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               ADB79C3307D4B7A200CA782A = {
+                       fileEncoding = 5;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       path = "foldertablecreate-helge-privcal.sqlite";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               ADB79C3407D4B7A200CA782A = {
+                       fileEncoding = 5;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.script.sh;
+                       path = "generate-folderinfo-sql-for-users-sqlite.sh";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               ADB79C3707D4B7AA00CA782A = {
+                       children = (
+                               ADB79C3207D4B7A200CA782A,
+                               ADB79C3307D4B7A200CA782A,
+                               ADB79C3407D4B7A200CA782A,
+                       );
+                       isa = PBXGroup;
+                       name = SQLite;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               ADB79C3A07D4B7B800CA782A = {
+                       children = (
+                               AD0CF97D071FE18800E72147,
+                               AD0CF978071FE18800E72147,
+                               AD0CF979071FE18800E72147,
+                               AD0CF97A071FE18800E72147,
+                               AD0CF97B071FE18800E72147,
+                               AD0CF97C071FE18800E72147,
+                               AD0CF97F071FE18800E72147,
+                               AD0CF980071FE18800E72147,
+                               AD0CF981071FE18800E72147,
+                               AD0CF982071FE18800E72147,
+                               AD0CF983071FE18800E72147,
+                       );
+                       isa = PBXGroup;
+                       name = PostgreSQL;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               ADB79C6907D4B92B00CA782A = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = "iCalRepeatableEntityObject+OCS.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               ADB79C6A07D4B92B00CA782A = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = "iCalRepeatableEntityObject+OCS.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
        };
        rootObject = AD0CF947071FE16800E72147;
 }
index 2c5bdd6047dc2a0bcf62c94eb2edeb0046de4ef2..d237ea4c9d7b70ebc719b3f493bd10cbb9514c3f 100644 (file)
@@ -2,7 +2,7 @@
 
 MAJOR_VERSION=0
 MINOR_VERSION=9
-SUBMINOR_VERSION:=21
+SUBMINOR_VERSION:=22
 
 # v0.9.19 requires libNGiCal       v4.5.40
 # v0.9.18 requires libNGiCal       v4.5.38
index 6435f95458563dbd16c71fd80294aba4a2f607cb..95bbc555ae555b10a0da16303b7126c4c1bb5739 100644 (file)
       sqlType    = "INT";
       allowsNull = NO;
     },
+    {
+      columnName = cylceenddate;
+      sqlType    = "INT";
+      allowsNull = YES;
+    },
     {
       columnName = title;
       sqlType    = "VARCHAR(1000)";
       sqlType    = "INT";
       allowsNull = YES;
     },
+    {
+      columnName = cycleinfo;
+      sqlType    = "VARCHAR(1000)";
+      allowsNull = YES;
+    },
     {
       columnName = ispublic;
       sqlType    = "INT";
diff --git a/OGoContentStore/iCalRepeatableEntityObject+OCS.h b/OGoContentStore/iCalRepeatableEntityObject+OCS.h
new file mode 100644 (file)
index 0000000..0fa62e1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+// $Id$
+
+
+#ifndef        __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
+#define        __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
+
+#include <NGiCal/NGiCal.h>
+
+@interface iCalRepeatableEntityObject (OCS)
+
+- (NSString *)cycleInfo;
+
+@end
+
+#endif /* __OGoContentStore_iCalRepeatableEntityObject_OCS_H_ */
diff --git a/OGoContentStore/iCalRepeatableEntityObject+OCS.m b/OGoContentStore/iCalRepeatableEntityObject+OCS.m
new file mode 100644 (file)
index 0000000..d36f9cb
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+// $Id$
+
+#include "iCalRepeatableEntityObject+OCS.h"
+#include "common.h"
+
+@implementation iCalRepeatableEntityObject (OCS)
+
+- (NSString *)cycleInfo {
+  NSMutableDictionary *cycleInfo;
+  NSMutableArray      *ma;
+  NSArray             *a;
+  unsigned            count;
+
+  if (![self isRecurrent])
+    return nil;
+
+  cycleInfo = [NSMutableDictionary dictionaryWithCapacity:3];
+
+  /* rules */
+  a     = [self recurrenceRules];
+  count = [a count];
+  if (count > 0) {
+    unsigned i;
+
+    ma = [NSMutableArray arrayWithCapacity:count];
+    for (i = 0; i < count; i++) {
+      iCalRecurrenceRule *rule;
+      
+      rule = [a objectAtIndex:i];
+      [ma addObject:[rule iCalRepresentation]];
+    }
+    [cycleInfo setObject:ma forKey:@"rules"];
+  }
+
+  /* exception rules */
+  a     = [self exceptionRules];
+  count = [a count];
+  if (count > 0) {
+    unsigned i;
+    
+    ma = [NSMutableArray arrayWithCapacity:count];
+    for (i = 0; i < count; i++) {
+      iCalRecurrenceRule *rule;
+      
+      rule = [a objectAtIndex:i];
+      [ma addObject:[rule iCalRepresentation]];
+    }
+    [cycleInfo setObject:ma forKey:@"exRules"];
+  }
+  
+  /* exception dates */
+  a     = [self exceptionDates];
+  count = [a count];
+  if (count > 0) {
+    unsigned i;
+    
+    ma = [NSMutableArray arrayWithCapacity:count];
+    for (i = 0; i < count; i++) {
+      NSCalendarDate *date;
+      
+      date = [a objectAtIndex:i];
+      [ma addObject:[date icalString]];
+    }
+    [cycleInfo setObject:ma forKey:@"exDates"];
+  }
+
+  return [cycleInfo description];
+}
+@end
index 710c65872f4cecef03e040cf80d35d19f9ce8c46..2877ae51f07782f34ee865d4e9607ca8ad5c3ce9 100644 (file)
@@ -10,7 +10,9 @@ CREATE TABLE SOGo_helge_privcal_quick (
   uid          VARCHAR(256)    NOT NULL,
   startdate    INT             NOT NULL,
   enddate      INT             NOT NULL,
+  cycleenddate INT             NULL,     -- enddate for cyclic events
   title        VARCHAR(1000)   NOT NULL,
+  cycleinfo    VARCHAR(1000)   NULL,     -- property list with cycle infos
   participants VARCHAR(100000) NOT NULL, -- the CNs of the participants
   isallday     INT             NULL,
   iscycle      INT             NULL,     -- client needs to fetch to resolve
index af9cf747d707ee431172a947fa9bc69b852f8c14..ed20827489cd5921e571f73e7c4b5b9f533d8560 100644 (file)
@@ -10,7 +10,9 @@ CREATE TABLE SOGo_helge_privcal_quick (
   uid          VARCHAR(256)    NOT NULL,
   startdate    INT             NOT NULL,
   enddate      INT             NOT NULL,
+  cycleenddate INT             NULL,     /* enddate for cyclic events */
   title        VARCHAR(1000)   NOT NULL,
+  cycleinfo    VARCHAR(1000)   NULL,     /* property list with cycle infos */
   participants VARCHAR(100000) NOT NULL, /* the CNs of the participants */
   isallday     INT             NULL,
   iscycle      INT             NULL,     /* client needs to fetch to resolve */
index 22b4b3dfe83535026dd194503c6d624f398c4365..00b49f5aba74a3580ee115cf590bf69a8b9c7c40 100755 (executable)
@@ -61,7 +61,9 @@ CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
   uid          VARCHAR(256)    NOT NULL,
   startdate    INT             NOT NULL,
   enddate      INT             NOT NULL,
+  cycleenddate INT             NULL,     /* enddate for cyclic events */
   title        VARCHAR(1000)   NOT NULL,
+  cycleinfo    VARCHAR(1000)   NULL,     /* property list with cycle infos */
   participants VARCHAR(100000) NOT NULL, /* the CNs of the participants */
   isallday     INT             NULL,
   iscycle      INT             NULL,     /* client needs to fetch to resolve */
index 2b054a3a6e600c47e4bf5fd7272804aa60682bc4..1e6984c3e1d053cc459648833e302f3ac19c46b2 100755 (executable)
@@ -72,7 +72,9 @@ CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
   uid          VARCHAR(256)    NOT NULL,
   startdate    INT             NOT NULL,
   enddate      INT             NOT NULL,
+  cycleenddate INT             NULL,     -- enddate for cyclic events
   title        VARCHAR(1000)   NOT NULL,
+  cycleinfo    VARCHAR(1000)   NULL,     -- property list with cycle infos
   participants VARCHAR(100000) NOT NULL, -- the CNs of the participants
   isallday     INT             NULL,
   iscycle      INT             NULL,     -- client needs to fetch to resolve
index 962d43620f5b1a712e7fda7ba4b966a26c3fdc14..17025ebd155508931f836db56282639aad41d7fa 100644 (file)
                        refType = 4;
                        sourceTree = "<group>";
                };
-               AD86234407CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailEditor.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234507CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailEditorAttach.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234607CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailFilterPanel.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234707CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailListView.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234807CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailMainFrame.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234907CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailMoveToPopUp.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234A07CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartAlternativeViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234B07CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartHTMLViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234C07CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartICalViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234D07CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartImageViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234E07CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartLinkViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86234F07CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartMessageViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86235007CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartMixedViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86235107CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailPartTextViewer.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86235207CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailSortableTableHeader.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86235307CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailToolbar.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
                AD86235407CA03D9004CD707 = {
                        fileEncoding = 5;
                        isa = PBXFileReference;
                        refType = 4;
                        sourceTree = "<group>";
                };
-               AD86235507CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailTree.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86235607CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailView.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD86235707CA03D9004CD707 = {
-                       fileEncoding = 5;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.xml;
-                       path = UIxMailWindowCloser.wox;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
                AD86235807CA03D9004CD707 = {
                        fileEncoding = 5;
                        isa = PBXFileReference;
                                AD86234107CA03D9004CD707,
                                AD86234207CA03D9004CD707,
                                AD86234307CA03D9004CD707,
-                               AD86234407CA03D9004CD707,
-                               AD86234507CA03D9004CD707,
-                               AD86234607CA03D9004CD707,
-                               AD86234707CA03D9004CD707,
-                               AD86234807CA03D9004CD707,
-                               AD86234907CA03D9004CD707,
-                               AD86234A07CA03D9004CD707,
-                               AD86234B07CA03D9004CD707,
-                               AD86234C07CA03D9004CD707,
-                               AD86234D07CA03D9004CD707,
-                               AD86234E07CA03D9004CD707,
-                               AD86234F07CA03D9004CD707,
-                               AD86235007CA03D9004CD707,
-                               AD86235107CA03D9004CD707,
-                               AD86235207CA03D9004CD707,
-                               AD86235307CA03D9004CD707,
                                AD86235407CA03D9004CD707,
-                               AD86235507CA03D9004CD707,
-                               AD86235607CA03D9004CD707,
-                               AD86235707CA03D9004CD707,
                                AD86235A07CA03D9004CD707,
                        );
                        isa = PBXGroup;
                        refType = 4;
                        sourceTree = "<group>";
                };
+               ADB79CAD07D4BF1600CA782A = {
+                       fileEncoding = 5;
+                       indentWidth = 8;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       path = ChangeLog;
+                       refType = 4;
+                       sourceTree = "<group>";
+                       tabWidth = 8;
+                       usesTabs = 1;
+               };
                ADBE3C490726AF4C000FEA6A = {
                        fileEncoding = 5;
                        indentWidth = 2;
                };
                E87206090692E3D00099CBBD = {
                        children = (
+                               ADB79CAD07D4BF1600CA782A,
                                E872064B0692E3D00099CBBD,
                                E87206420692E3D00099CBBD,
                                ADDF4BE606DCF5E200C4E7F8,
index 16cf5827b4c3f12d55752abd3b302e87d8ff1c45..0073631938e06a68b36597a2614199020e77ee4e 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-01  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * SOGoAppointmentFolder.m: significantly changed handling of cyclic
+         events. Information for cyclic event calculation is now contained
+         in the quick info, making full fetches obsolete - performance
+         should improve significantly this way (v0.9.28)
+
 2005-02-22  Helge Hess  <helge.hess@skyrix.com>
 
        * SOGoAppointmentFolder.m: minor code cleanups (v0.9.27)
index 92c9390173dbe5c1ce4326d17d3996868caed4ce..7b62a57806f1fabae67cf75976d778fbf4084781 100644 (file)
@@ -141,65 +141,89 @@ static NSTimeZone *MET    = nil;
   
   md = [[_record mutableCopy] autorelease];
  
-  if (![[_record valueForKey:@"iscycle"] intValue]) {
-    if ((tmp = [_record objectForKey:@"startdate"])) {
-      tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
-                                   (NSTimeInterval)[tmp unsignedIntValue]];
-      [tmp setTimeZone:[self viewTimeZone]];
-      if (tmp) [md setObject:tmp forKey:@"startDate"];
-      [tmp release];
-    }
-    else
-      [self logWithFormat:@"missing 'startdate' in record?"];
-
-    if ((tmp = [_record objectForKey:@"enddate"])) {
-      tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
-                                   (NSTimeInterval)[tmp unsignedIntValue]];
-      [tmp setTimeZone:[self viewTimeZone]];
-      if (tmp) [md setObject:tmp forKey:@"endDate"];
-      [tmp release];
-    }
-    else
-      [self logWithFormat:@"missing 'enddate' in record?"];
-  }
-  else {
-    /* cycle is in _r */
-    tmp = [_r startDate];
+  if ((tmp = [_record objectForKey:@"startdate"])) {
+    tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
+          (NSTimeInterval)[tmp unsignedIntValue]];
     [tmp setTimeZone:[self viewTimeZone]];
-    [md setObject:tmp forKey:@"startDate"];
-    tmp = [_r endDate];
+    if (tmp) [md setObject:tmp forKey:@"startDate"];
+    [tmp release];
+  }
+  else
+    [self logWithFormat:@"missing 'startdate' in record?"];
+
+  if ((tmp = [_record objectForKey:@"enddate"])) {
+    tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
+          (NSTimeInterval)[tmp unsignedIntValue]];
     [tmp setTimeZone:[self viewTimeZone]];
-    [md setObject:tmp forKey:@"endDate"];
+    if (tmp) [md setObject:tmp forKey:@"endDate"];
+    [tmp release];
   }
+  else
+    [self logWithFormat:@"missing 'enddate' in record?"];
+
   return md;
 }
 
-- (void)_flattenCycleRecord:(NSDictionary *)row
+- (NSMutableDictionary *)fixupCycleRecord:(NSDictionary *)_record
+  cycleRange:(NGCalendarDateRange *)_r
+{
+  NSMutableDictionary *md;
+  id tmp;
+  
+  md = [[_record mutableCopy] autorelease];
+  
+  /* cycle is in _r */
+  tmp = [_r startDate];
+  [tmp setTimeZone:[self viewTimeZone]];
+  [md setObject:tmp forKey:@"startDate"];
+  tmp = [_r endDate];
+  [tmp setTimeZone:[self viewTimeZone]];
+  [md setObject:tmp forKey:@"endDate"];
+  
+  return md;
+}
+
+- (void)_flattenCycleRecord:(NSDictionary *)_row
   forRange:(NGCalendarDateRange *)_r
-  intoArray:(NSMutableArray *)ma
+  intoArray:(NSMutableArray *)_ma
 {
-  NSString  *uid;
-  id        aptObject;
-  iCalEvent *apt;
-  NSArray   *ranges;
-  unsigned  k, rCount;
-      
-  uid        = [row valueForKey:@"uid"];
-  
-#warning FIXME: lookup done by name, not by UID
-  // TODO: this is wrong, we need to lookup the appointment by UID, not name
-  aptObject  = [self appointmentWithName:uid inContext:nil];
-  
-  apt        = [aptObject event];
-  ranges     = [apt recurrenceRangesWithinCalendarDateRange:_r];
-  rCount     = [ranges count];
-  for (k = 0; k < rCount; k++) {
+  NSMutableDictionary *row;
+  NSDictionary        *cycleinfo;
+  NSCalendarDate      *startDate, *endDate;
+  NGCalendarDateRange *fir;
+  NSArray             *rules, *exRules, *exDates, *ranges;
+  unsigned            i, count;
+
+  cycleinfo  = [[_row objectForKey:@"cycleinfo"] propertyList];
+  if (cycleinfo == nil) {
+    [self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@", _row];
+    return;
+  }
+
+  row = [self fixupRecord:_row fetchRange:_r];
+  [row removeObjectForKey:@"cycleinfo"];
+
+  startDate = [row objectForKey:@"startDate"];
+  endDate   = [row objectForKey:@"endDate"];
+  fir       = [NGCalendarDateRange calendarDateRangeWithStartDate:startDate
+                                   endDate:endDate];
+  rules     = [cycleinfo objectForKey:@"rules"];
+  exRules   = [cycleinfo objectForKey:@"exRules"];
+  exDates   = [cycleinfo objectForKey:@"exDates"];
+
+  ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange:_r
+                                     firstInstanceCalendarDateRange:fir
+                                     recurrenceRules:rules
+                                     exceptionRules:exRules
+                                     exceptionDates:exDates];
+  count = [ranges count];
+  for (i = 0; i < count; i++) {
     NGCalendarDateRange *rRange;
     id fixedRow;
     
-    rRange   = [ranges objectAtIndex:k];
-    fixedRow = [self fixupRecord:row fetchRange:rRange];
-    if (fixedRow != nil) [ma addObject:fixedRow];
+    rRange   = [ranges objectAtIndex:i];
+    fixedRow = [self fixupCycleRecord:row cycleRange:rRange];
+    if (fixedRow != nil) [_ma addObject:fixedRow];
   }
 }
 
@@ -207,7 +231,6 @@ static NSTimeZone *MET    = nil;
   fetchRange:(NGCalendarDateRange *)_r
 {
   // TODO: is the result supposed to be sorted by date?
-  // TODO: move cycle handling out of fixup
   NSMutableArray *ma;
   unsigned i, count;
 
@@ -215,24 +238,37 @@ static NSTimeZone *MET    = nil;
   if ((count = [_records count]) == 0)
     return _records;
   
-  // TODO: inefficient, does a lot of fetches for cycles, separate cycle
-  //       handling from fixup!
   ma = [NSMutableArray arrayWithCapacity:count];
   for (i = 0; i < count; i++) {
     id row; // TODO: what is the type of the record?
     
     row = [_records objectAtIndex:i];
-    if ([[row valueForKey:@"iscycle"] intValue] != 0) {
-      [self _flattenCycleRecord:row forRange:_r intoArray:ma];
-    }
-    else {
-      row = [self fixupRecord:row fetchRange:_r];
-      if (row != nil) [ma addObject:row];
-    }
+    row = [self fixupRecord:row fetchRange:_r];
+    if (row != nil) [ma addObject:row];
   }
   return ma;
 }
 
+- (NSArray *)fixupCyclicRecords:(NSArray *)_records
+  fetchRange:(NGCalendarDateRange *)_r
+{
+  // TODO: is the result supposed to be sorted by date?
+  NSMutableArray *ma;
+  unsigned i, count;
+  
+  if (_records == nil) return nil;
+  if ((count = [_records count]) == 0)
+    return _records;
+  
+  ma = [NSMutableArray arrayWithCapacity:count];
+  for (i = 0; i < count; i++) {
+    id row; // TODO: what is the type of the record?
+    
+    row = [_records objectAtIndex:i];
+    [self _flattenCycleRecord:row forRange:_r intoArray:ma];
+  }
+  return ma;
+}
 
 - (NSArray *)fetchFields:(NSArray *)_fields
   fromFolder:(OCSFolder *)_folder
@@ -240,6 +276,7 @@ static NSTimeZone *MET    = nil;
   to:(NSCalendarDate *)_endDate 
 {
   EOQualifier         *qualifier;
+  NSMutableArray      *fields, *ma = nil;
   NSArray             *records;
   NSString            *sql;
   NGCalendarDateRange *r;
@@ -253,24 +290,56 @@ static NSTimeZone *MET    = nil;
   r = [NGCalendarDateRange calendarDateRangeWithStartDate:_startDate
                            endDate:_endDate];
 
+  /* prepare mandatory fields */
+
+  fields    = [NSMutableArray arrayWithArray:_fields];
+  [fields addObject:@"uid"];
+  [fields addObject:@"startdate"];
+  [fields addObject:@"enddate"];
+  
   if (debugOn)
     [self debugWithFormat:@"should fetch (%@=>%@) ...", _startDate, _endDate];
   
-  sql = [NSString stringWithFormat:@"(startdate < %d) AND (enddate > %d)",
+  sql = [NSString stringWithFormat:@"(startdate < %d) AND (enddate > %d)"
+                                   @" AND (iscycle = 0)",
+                 (unsigned int)[_endDate   timeIntervalSince1970],
+                 (unsigned int)[_startDate timeIntervalSince1970]];
+
+  /* fetch non-recurrent apts first */
+  qualifier = [EOQualifier qualifierWithQualifierFormat:sql];
+
+  records   = [_folder fetchFields:fields matchingQualifier:qualifier];
+  if (records != nil) {
+    records = [self fixupRecords:records fetchRange:r];
+    if (debugOn)
+      [self logWithFormat:@"fetched %i records: %@", [records count], records];
+    ma = [NSMutableArray arrayWithArray:records];
+  }
+
+  /* fetch recurrent apts now */
+  sql = [NSString stringWithFormat:@"(startdate < %d) AND (cycleenddate > %d)"
+                                   @" AND (iscycle = 1)",
                  (unsigned int)[_endDate   timeIntervalSince1970],
                  (unsigned int)[_startDate timeIntervalSince1970]];
   qualifier = [EOQualifier qualifierWithQualifierFormat:sql];
 
-  records = [_folder fetchFields:_fields matchingQualifier:qualifier];
-  if (records == nil) {
+  [fields addObject:@"cycleinfo"];
+
+  records = [_folder fetchFields:fields matchingQualifier:qualifier];
+  if (records != nil) {
+    if (debugOn)
+      [self logWithFormat:@"fetched %i cyclic records: %@",
+        [records count], records];
+    records = [self fixupCyclicRecords:records fetchRange:r];
+    if (!ma) ma = [NSMutableArray arrayWithCapacity:[records count]];
+    [ma addObjectsFromArray:records];
+  }
+  else if (ma == nil) {
     [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
     return nil;
   }
-  
-  records = [self fixupRecords:records fetchRange:r];
-  if (debugOn)
-    [self logWithFormat:@"fetched %i records: %@", [records count], records];
-  return records;
+
+  return ma;
 }
 
 /* override this in subclasses */
@@ -295,8 +364,7 @@ static NSTimeZone *MET    = nil;
 {
   static NSArray *infos = nil; // TODO: move to a plist file
   if (infos == nil) {
-    infos = [[NSArray alloc] initWithObjects:@"uid", @"startdate", @"enddate",
-                                       nil];
+    infos = [[NSArray alloc] init];
   }
   return [self fetchFields:infos from:_startDate to:_endDate];
 }
@@ -308,9 +376,9 @@ static NSTimeZone *MET    = nil;
   static NSArray *infos = nil; // TODO: move to a plist file
   if (infos == nil) {
     infos = [[NSArray alloc] initWithObjects:
-                        @"uid", @"startdate", @"enddate", @"title", 
-                        @"location", @"orgmail", @"status", @"ispublic", 
-                        @"iscycle", @"isallday", nil];
+                               @"title", 
+                               @"location", @"orgmail", @"status", @"ispublic", 
+                               @"isallday", nil];
   }
   return [self fetchFields:infos
                from:_startDate
@@ -322,13 +390,12 @@ static NSTimeZone *MET    = nil;
 {
   static NSArray *infos = nil; // TODO: move to a plist file
   if (infos == nil) {
-    infos = [[NSArray alloc] initWithObjects:@"uid", @"startdate", @"enddate",
+    infos = [[NSArray alloc] initWithObjects:
                                @"title", @"location", @"orgmail",
-                               @"status", @"ispublic", @"iscycle",
+                               @"status", @"ispublic",
                                @"isallday", @"isopaque",
                                @"participants", @"partmails",
-                               @"partstates", @"sequence",
-                             nil];
+                               @"partstates", @"sequence", nil];
   }
   return [self fetchFields:infos
                from:_startDate
index 00d21930e702ea9c7403c9a34dceae484b94998f..78c27fd99d17d0c8032a41e8464a877755f7546d 100644 (file)
@@ -1,7 +1,8 @@
 # Version file
 
-SUBMINOR_VERSION:=27
+SUBMINOR_VERSION:=28
 
+# v0.9.28 requires NGiCal  v4.5.47
 # v0.9.26 requires libSOGo v0.9.30
 # v0.9.19 requires NGiCal  v4.5.36
 # v0.9.13 requires libSOGo v0.9.26
index d9d5a784d971a6acdfcc669231d843dd4cfc6723..29b175f8766294c7318dbc2b130b815b48d245f5 100644 (file)
@@ -1,3 +1,7 @@
+2005-03-01  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * UIxCalDateLabel.m: fixed heuristics for month label (v0.9.117)
+
 2005-02-21  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * v0.9.116
index 3e31cec537fceb1711e3b7f7ce2db479506415ba..d594afc7df5b6d558b7d974ae37a94c5722eddf3 100644 (file)
 
 - (NSString *)monthLabel {
   NSString *l;
+  unsigned diff;
 
-  l = [self localizedNameForMonthOfYear:[self->startDate monthOfYear]];
+  diff = [self->startDate monthsBetweenDate:self->endDate];
+  if (diff == 0) {
+    l = [self localizedNameForMonthOfYear:[self->startDate monthOfYear]];
+  }
+  else {
+    NSCalendarDate *date;
+
+    date = [self->startDate dateByAddingYears:0 months:0 days:15];
+    l    = [self localizedNameForMonthOfYear:[date monthOfYear]];
+  }
   return [NSString stringWithFormat:@"%@ %d",
                   l, [self->startDate yearOfCommonEra]];
 }
index 73dc879d3a2ce16512a02f8e79f19a3b1c38e90b..9094796553ada8e970b152f5f89d192efab992ec 100644 (file)
@@ -1,6 +1,6 @@
 # Version file
 
-SUBMINOR_VERSION:=116
+SUBMINOR_VERSION:=117
 
 # v0.9.115 requires NGiCal       v4.5.44
 # v0.9.113 requires libSOGo      v0.9.30