]> err.no Git - sope/commitdiff
fixed a bug in the sort order generator, major reorgs
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 13 Jan 2005 23:18:18 +0000 (23:18 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 13 Jan 2005 23:18:18 +0000 (23:18 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@517 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-gdl1/GDLAccess/ChangeLog
sope-gdl1/GDLAccess/EOAdaptorDataSource.m
sope-gdl1/GDLAccess/Version

index 8c7bd601d9f4e927a6a46b93cbf681ae7f647def..7bee603f8a4e9681feda37785627cae3a97ca220 100644 (file)
@@ -1,3 +1,12 @@
+2005-01-14  Helge Hess  <helge.hess@opengroupware.org>
+
+       * EOAdaptorDataSource.m: fixed a bug in the sorting code, the "AS" was
+         missing in the SQL rename statement (v4.5.46)
+
+2005-01-13  Helge Hess  <helge.hess@opengroupware.org>
+
+       * EOAdaptorDataSource.m: improved -description (v4.5.45)
+
 2005-01-04  Helge Hess  <helge.hess@opengroupware.org>
 
        * EOAttribute.m, EOFaultHandler.m, EODatabaseFaultResolver.m: added 
index 38ca909068eae0c61cc7e1b1f954e169d062025b..87482cff864879ebf452b8272acdef2ae03acae8 100644 (file)
@@ -3,8 +3,7 @@
    
    Copyright (C) SKYRIX Software AG and Helge Hess
 
-   Author: Helge Hess (helge.hess@opengroupware.org)
-   Date:   1999-2004
+   Date:   1999-2005
 
    This file is part of the GNUstep Database Library.
 
@@ -23,7 +22,6 @@
    If not, write to the Free Software Foundation,
    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
-// $Id: EOAdaptorDataSource.m 1 2004-08-20 10:38:46Z znek $
 
 /*
   column-names must have small letterso
@@ -64,12 +62,19 @@ static EONull *null = nil;
 @end /* EOQualifier(SqlExpression) */
 
 @interface EOAdaptorDataSource(Private)
+
 - (NSMutableString *)_selectListWithChannel:(EOAdaptorChannel *)_adChan;
 - (NSString *)_whereExprWithChannel:(EOAdaptorChannel *)_adChan;
 - (NSString *)_whereClauseForGlobaID:(EOKeyGlobalID *)_gid
   adaptor:(EOAdaptor *)_adaptor channel:(EOAdaptorChannel *)_adChan;
+
+- (NSString *)_orderByExprForAttributes:(NSArray *)_attrs 
+  andPatchSelectList:(NSMutableString *)selectList
+  withChannel:(EOAdaptorChannel *)_adChan;
+
 - (NSDictionary *)_mapAttrsWithValues:(NSDictionary *)_keyValues
   tableName:(NSString *)_tableName channel:(EOAdaptorChannel *)_adChan;
+
 @end /* EOAdaptorDataSource(Private) */
 
 @interface EOAdaptorDataSource(Internals)
@@ -83,6 +88,7 @@ static EONull *null = nil;
 
 @implementation EOAdaptorDataSource
 
+static Class NSCalendarDateClass = nil;
 static NSNotificationCenter *nc = nil;
 
 static NSNotificationCenter *getNC(void ) {
@@ -95,8 +101,9 @@ static NSNotificationCenter *getNC(void ) {
   NSAssert2([super version] == 1,
             @"invalid superclass (%@) version %i !",
             NSStringFromClass([self superclass]), [super version]);
-  if (null == nil)
-    null = [[EONull null] retain];
+
+  null = [[EONull null] retain];
+  NSCalendarDateClass = [NSCalendarDate class];
 }
 + (int)version {
   return [super version] + 1; /* v2 */
@@ -239,7 +246,7 @@ static NSNotificationCenter *getNC(void ) {
   /* TODO: split up this HUGE method! */
   NSString         *entityName  = nil;
   NSString         *whereExpr   = nil;
-  NSMutableString  *orderByExpr = nil;
+  NSString         *orderByExpr = nil;
   NSMutableString  *selectList  = nil;  
   NSMutableString  *expression  = nil;
   NSMutableArray   *result      = nil;
@@ -253,6 +260,7 @@ static NSNotificationCenter *getNC(void ) {
   BOOL             localComTrans;
 
   if (self->fetchSpecification == nil) {
+    // TODO: make that a lastException and just return nil
     [NSException raise:NSInvalidArgumentException
                 format:@"fetchSpecification required for table name"];
     return nil;
@@ -334,105 +342,12 @@ static NSNotificationCenter *getNC(void ) {
     RELEASE(qualifierKeys); qualifierKeys = nil;
   }
   
-  whereExpr  = [self _whereExprWithChannel:adChan];
-  selectList = [self _selectListWithChannel:adChan];
-  { /* order by expr */
-    NSEnumerator   *enumerator   = nil;
-    EOSortOrdering *sortOrdering = nil;
-    int            orderCnt      = 0;
-
-    enumerator = [[self->fetchSpecification sortOrderings] objectEnumerator];
-
-    while ((sortOrdering = [enumerator nextObject])) {
-      SEL         selector    = NULL;
-      NSString    *key        = nil;
-      EOAttribute *keyAttr    = nil;
-      int         order       = 0; /* 0 - not used; 1 - asc; 2 - desc */
-      BOOL        inSensitive = NO;
-      NSString    *orderTmp   = nil;
-
-      if (orderByExpr == nil) {
-        orderByExpr = [NSMutableString stringWithCapacity:64];
-      }
-      else {
-        [orderByExpr appendString:@", "];
-      }
-      if ((selector = [sortOrdering selector])) {
-        if (SEL_EQ(selector, EOCompareAscending)) {
-          order = 1;
-        }
-        else if (SEL_EQ(selector, EOCompareDescending)) {
-          order = 2;
-        }
-        else if (SEL_EQ(selector, EOCompareCaseInsensitiveAscending)) {
-         order       = 1;
-         inSensitive = YES;
-       }
-        else if (SEL_EQ(selector, EOCompareCaseInsensitiveDescending)) {
-         inSensitive = YES;
-         order       = 2;
-       }
-      }
-      key = [sortOrdering key];
-
-      if (key == nil || [key length] == 0) {
-        NSLog(@"WARNING[%s]: wrong key in sortordering %@",
-              __PRETTY_FUNCTION__, key);
-        continue;
-      }
-      {
-        NSEnumerator *en = nil;
-        id           obj = nil;
-
-        key = [key lowercaseString];
-        en  = [attrs objectEnumerator];
-        while ((obj = [en nextObject])) {
-          if ([[[(EOAttribute *)obj columnName] lowercaseString]
-                              isEqualToString:key])
-            break;
-        }
-        if (obj == nil) {
-          RELEASE(self->__attributes); self->__attributes = nil;
-          RELEASE(self->__qualifier);  self->__qualifier  = nil;
-          RELEASE(expression);         expression         = nil;
-          [self rollbackTransaction];
-          [[[InvalidAttributeException alloc]
-                    initWithFormat:@"couldn`t find EOAttribute for SortOrdering"
-                                   @" %@ Attributes %@",
-                                   sortOrdering, attrs] raise];
-        }
-        keyAttr = obj;
-      }
-      key = [adaptor formatAttribute:keyAttr];
-      orderTmp = [NSString stringWithFormat:@"order_by_expr_%d", orderCnt++];
-      [orderByExpr appendString:orderTmp];
-      if (order == 1) {
-        [orderByExpr appendString:@" ASC"];
-      }
-      else if (order == 2) {
-        [orderByExpr appendString:@" DESC"];
-      }
-      { /* manipulate select expr */
-        if (inSensitive) {
-          if ([[keyAttr valueClassName] isEqualToString:@"NSString"]) {
-              key = [NSString stringWithFormat:@"LOWER(%@)", key];
-          }
-          else
-            NSLog(@"WARNING[%s]: inSensitive expression for no text attribute",
-                  __PRETTY_FUNCTION__);
-        }
-        {
-          NSString *str = nil;
-
-          str = [key stringByAppendingString:@" "];
-          str = [str stringByAppendingString:orderTmp];
-          str = [str stringByAppendingString:@", "];
-          
-          [selectList insertString:str atIndex:0];
-        }
-      }
-    }
-  }  
+  whereExpr   = [self _whereExprWithChannel:adChan];
+  selectList  = [self _selectListWithChannel:adChan];
+  orderByExpr = [self _orderByExprForAttributes:attrs
+                     andPatchSelectList:selectList
+                     withChannel:adChan];
+  
   expression = [[NSMutableString alloc] initWithCapacity:256];
   [expression appendString:@"SELECT "];
 
@@ -462,19 +377,20 @@ static NSNotificationCenter *getNC(void ) {
   }
   result = [NSMutableArray arrayWithCapacity:64];
   {
-    NSMutableDictionary *row       = nil;
+    NSMutableDictionary *row = nil;
     unsigned fetchCnt   = 0;
     unsigned fetchLimit = 0;
     unsigned attrCnt    = 0;
     id       *values    = NULL;
     id       *keys      = NULL;
-
+    
+    /* Note: those are reused in the inner loop */
     attrCnt    = [attrs count];
     values     = calloc(attrCnt + 2, sizeof(id));
     keys       = calloc(attrCnt + 2, sizeof(id));
     fetchLimit = [self->fetchSpecification fetchLimit];
     
-    while ((row = [adChan fetchAttributes:attrs withZone:NULL])) {
+    while ((row = [adChan fetchAttributes:attrs withZone:NULL]) != nil) {
       NSEnumerator        *enumerator = nil;
       id                  attr        = nil;
       int                 rowCnt      = 0;
@@ -485,26 +401,18 @@ static NSNotificationCenter *getNC(void ) {
       pKeyVs     = calloc(pKeyCnt, sizeof(id));
       enumerator = [attrs objectEnumerator];
       
-      while ((attr = [enumerator nextObject])) {
+      while ((attr = [enumerator nextObject]) != nil) {
         id       obj;
         NSString *cn;
 
-
         obj = [row objectForKey:[(EOAttribute *)attr name]];
-
+       
         if (obj == nil)
           continue;
-
-        if (tz) {
-          static Class NSCalendarDateClass = nil;
-          
-          if (NSCalendarDateClass == nil)
-            NSCalendarDateClass = [NSCalendarDate class];
-        
-          if ([obj isKindOfClass:NSCalendarDateClass]) {
-            [obj setTimeZone:tz];
-          }
-       }
+       
+        if (tz != nil && [obj isKindOfClass:NSCalendarDateClass])
+         [obj setTimeZone:tz];
+       
         cn             = [[attr columnName] lowercaseString];
         values[rowCnt] = obj;
         keys[rowCnt]   = cn;
@@ -546,24 +454,23 @@ static NSNotificationCenter *getNC(void ) {
       }
       fetchCnt++;
       r = [[NSMutableDictionary alloc]
-                                initWithObjects:values forKeys:keys count:rowCnt];
+           initWithObjects:values forKeys:keys count:rowCnt];
       [result addObject:r];
-      RELEASE(r); r = nil;
-      free(pKeyVs); pKeyVs = NULL;
-      if (fetchLimit == fetchCnt) {
+      [r release]; r = nil;
+      if (pKeyVs) free(pKeyVs); pKeyVs = NULL;
+      if (fetchLimit == fetchCnt)
         break;
-      }
     }
-    free(values); values = NULL;
-    free(keys);   keys   = NULL;
+    if (values) free(values); values = NULL;
+    if (keys)   free(keys);   keys   = NULL;
   }
   [adChan cancelFetch];
   if (localComTrans)
     [self commitTransaction];
   
-  RELEASE(expression);         expression         = nil;
-  RELEASE(self->__qualifier);  self->__qualifier  = nil;
-  RELEASE(self->__attributes); self->__attributes = nil;
+  [expression         release]; expression         = nil;
+  [self->__qualifier  release]; self->__qualifier  = nil;
+  [self->__attributes release]; self->__attributes = nil;
   return result;
 }
 
@@ -957,12 +864,28 @@ static NSNotificationCenter *getNC(void ) {
 }
 
 - (EOFetchSpecification *)fetchSpecification {
+  /* 
+     Note: the copy is intended, since the fetchspec is mutable, the consumer
+           could otherwise modify it "behind the scenes"
+  */
   return [[self->fetchSpecification copy] autorelease];
 }
 
+/* description */
+
 - (NSString *)description {
-  return [NSString stringWithFormat:@"%@: adaptorChannel: %@",
-                   [super description], self->adChannel];
+  NSMutableString *ms;
+  
+  ms = [NSMutableString stringWithCapacity:128];
+  [ms appendFormat:@"<%@[0x%08X]:", NSStringFromClass([self class]), self];
+
+  if (self->fetchSpecification != nil)
+    [ms appendFormat:@" fspec=%@", self->fetchSpecification];
+  if (self->adChannel != nil)
+    [ms appendFormat:@" channel=%@", self->adChannel];
+  
+  [ms appendString:@">"];
+  return ms;
 }
 
 @end /* EOAdaptorDataSource */
@@ -1057,6 +980,128 @@ static NSNotificationCenter *getNC(void ) {
   return [qual sqlExpressionWithAdaptor:adaptor attributes:attrs];
 }
 
+- (NSException *)_couldNotFindSortAttributeInAttributes:(NSArray *)_attrs
+  forSortOrdering:(EOSortOrdering *)_so
+{
+  return [[InvalidAttributeException alloc]
+          initWithFormat:@"could not find EOAttribute for SortOrdering"
+          @" %@ Attributes %@", _so, _attrs];
+}
+
+- (EOAttribute *)findAttributeForKey:(NSString *)key 
+  inAttributes:(NSArray *)_attrs
+{
+  NSEnumerator *en;
+  EOAttribute  *obj;
+  
+  key = [key lowercaseString];
+  en  = [_attrs objectEnumerator];
+  while ((obj = [en nextObject]) != nil) {
+    if ([[[obj columnName] lowercaseString] isEqualToString:key])
+      break;
+  }
+  return obj;
+}
+
+- (NSString *)_orderByExprForAttributes:(NSArray *)_attrs 
+  andPatchSelectList:(NSMutableString *)selectList
+  withChannel:(EOAdaptorChannel *)_adChan
+{
+  NSMutableString *orderByExpr;
+  NSEnumerator   *enumerator   = nil;
+  EOSortOrdering *sortOrdering = nil;
+  int            orderCnt      = 0;
+  EOAdaptor      *adaptor;
+
+  adaptor = [[_adChan adaptorContext] adaptor];
+  
+  orderByExpr = nil;
+  enumerator = [[self->fetchSpecification sortOrderings] objectEnumerator];
+  while ((sortOrdering = [enumerator nextObject]) != nil) {
+      SEL         selector    = NULL;
+      NSString    *key        = nil;
+      EOAttribute *keyAttr    = nil;
+      int         order       = 0; /* 0 - not used; 1 - asc; 2 - desc */
+      BOOL        inSensitive = NO;
+      NSString    *orderTmp   = nil;
+
+      if (orderByExpr == nil)
+        orderByExpr = [NSMutableString stringWithCapacity:64];
+      else
+        [orderByExpr appendString:@", "];
+      
+      if ((selector = [sortOrdering selector])) {
+        if (SEL_EQ(selector, EOCompareAscending))
+          order = 1;
+        else if (SEL_EQ(selector, EOCompareDescending))
+          order = 2;
+        else if (SEL_EQ(selector, EOCompareCaseInsensitiveAscending)) {
+         order       = 1;
+         inSensitive = YES;
+       }
+        else if (SEL_EQ(selector, EOCompareCaseInsensitiveDescending)) {
+         order       = 2;
+         inSensitive = YES;
+       }
+      }
+      key = [sortOrdering key];
+      
+      if (key == nil || [key length] == 0) {
+        NSLog(@"WARNING[%s]: no key in sortordering %@",
+             __PRETTY_FUNCTION__, key);
+        continue;
+      }
+      {
+        EOAttribute  *obj;
+       
+        key = [key lowercaseString];
+       obj = [self findAttributeForKey:key inAttributes:_attrs];
+        if (obj == nil) {
+          [self->__attributes release]; self->__attributes = nil;
+          [self->__qualifier  release]; self->__qualifier  = nil;
+#if 0 // TODO: memleak in error case
+          [expression         release]; expression         = nil;
+#endif
+          [self rollbackTransaction];
+         
+         [[self _couldNotFindSortAttributeInAttributes:_attrs
+                forSortOrdering:sortOrdering] raise];
+         return nil;
+        }
+       
+        keyAttr = obj;
+      }
+      key      = [adaptor formatAttribute:keyAttr];
+      orderTmp = [NSString stringWithFormat:@"order%d", orderCnt];
+      orderCnt++;
+      [orderByExpr appendString:orderTmp];
+      if (order == 1)
+        [orderByExpr appendString:@" ASC"];
+      else if (order == 2)
+        [orderByExpr appendString:@" DESC"];
+      
+      /* manipulate select expr */
+      if (inSensitive) {
+          if ([[keyAttr valueClassName] isEqualToString:@"NSString"]) {
+              key = [NSString stringWithFormat:@"LOWER(%@)", key];
+          }
+          else
+            NSLog(@"WARNING[%s]: inSensitive expression for no text attribute",
+                  __PRETTY_FUNCTION__);
+      }
+      {
+       NSString *str = nil;
+
+       str = [key stringByAppendingString:@" AS "];
+       str = [str stringByAppendingString:orderTmp];
+       str = [str stringByAppendingString:@", "];
+       
+       [selectList insertString:str atIndex:0];
+      }
+  }
+  return orderByExpr;
+}
+
 - (NSMutableString *)_selectListWithChannel:(EOAdaptorChannel *)_adChan {
   NSArray         *attrs      = nil;
   NSEnumerator    *enumerator = nil;
index 6053c6f7a2b02babe820f9a14b93d8c915f7ee4f..3e648f9518ad9e2a6f4d354849fed4dd84aa96f5 100644 (file)
@@ -1,3 +1,3 @@
 # version file
 
-SUBMINOR_VERSION:=44
+SUBMINOR_VERSION:=46