]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1120 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 24 Jul 2007 20:31:48 +0000 (20:31 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Tue, 24 Jul 2007 20:31:48 +0000 (20:31 +0000)
21 files changed:
ChangeLog
Main/SOGo.m
OGoContentStore/OCSContactFieldExtractor.m
OGoContentStore/OCSiCalFieldExtractor.m
OGoContentStore/appointment.ocs
OGoContentStore/contact.ocs
Scripts/sogo [deleted file]
Scripts/sogo-init.d-debian
Scripts/sogo-init.d-redhat
Scripts/sogod-0.9
Scripts/sql-update-20070724.sh [new file with mode: 0755]
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/Contacts/SOGoContactGCSFolder.m
SoObjects/Contacts/SOGoContactLDAPFolder.m
SoObjects/SOGo/AgenorUserDefaults.m
SoObjects/SOGo/LDAPSource.m
SoObjects/SOGo/SOGoUser.m
UI/Contacts/UIxContactsListView.m
UI/MainUI/AgenorProfile.sql
UI/Scheduler/UIxCalListingActions.m
UI/Templates/ContactsUI/UIxContactsListView.wox

index 8c87a9450b4db452e680498f5faf84d348d83a6e..2cfff9547232a08ac1dd05e22bd589f0342df95b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2007-07-24  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Contacts/UIxContactsListView.m ([-displayName]): removed
+       method.
+       ([UIxContactsListView -defaultSortKey]): changed to "displayName".
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.m
+       ([SOGoContactLDAPFolder
+       -lookupContactsWithFilter:filtersortBy:sortKeyordering:sortOrdering]):
+       translate the returned records to a normalized form.
+
+       * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
+       -lookupContactsWithFilter:filtersortBy:sortKeyordering:sortOrdering]):
+       translate the returned records to a normalized form.
+
+       * UI/Scheduler/UIxCalListingActions.m,
+       UI/Contacts/UIxContactsListView.m, SoObjects/SOGo/SOGoUser.m,
+       SoObjects/SOGo/AgenorUserDefaults.m,
+       SoObjects/Contacts/SOGoContactGCSFolder.m,
+       SoObjects/Appointments/SOGoAppointmentFolder.m,
+       OGoContentStore/OCSiCalFieldExtractor.m,
+       OGoContentStore/OCSContactFieldExtractor.m: prefixed all quick
+       table fields with "c_".
+
+2007-07-23  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/LDAPSource.m ([LDAPSource +initialize]): query
+       the values for SOGoLDAPQueryLimit and SOGoLDAPQueryTimeout from
+       the application settings. If set, both limit will influence the
+       maximum size of the resultsets and the time taken to solve them.
+       ([LDAPSource -_initLDAPConnection]): initialize the limits.
+
 2007-07-22  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder -davNamespaces]): added new overriden
index 0ee12f43c1aae009650187b94b3a9e784b91a515..527d082b66dbd68ea02d22462c33b08fac406da0 100644 (file)
@@ -174,9 +174,6 @@ static BOOL debugObjectAllocation = NO;
     [tc cancelFetch];
 
   [cm releaseChannel: tc];
-
-//   [self terminate];
-//   NSLog (@"not yet");
 }
 
 - (BOOL) _checkMandatoryTables
index f1f6a56b838baf5b3e6637df3fb68ca580db8eea..b52b567e88f1f5469f033b7eab285fcc8788a538 100644 (file)
 
   value = [vCard fn];
   if (value)
-    [fields setObject: value forKey: @"cn"];
+    [fields setObject: value forKey: @"c_cn"];
   values = [vCard n];
   if (values)
     {
       max = [values count];
       if (max > 0)
         {
-          [fields setObject: [values objectAtIndex: 0] forKey: @"sn"];
+          [fields setObject: [values objectAtIndex: 0] forKey: @"c_sn"];
           if (max > 1)
             [fields setObject: [values objectAtIndex: 1]
-                    forKey: @"givenName"];
+                    forKey: @"c_givenName"];
         }
     }
   value = [vCard preferredTel];
   if (value)
-    [fields setObject: value forKey: @"telephoneNumber"];
+    [fields setObject: value forKey: @"c_telephoneNumber"];
   value = [vCard preferredEMail];
   if (value)
-    [fields setObject: value forKey: @"mail"];
+    [fields setObject: value forKey: @"c_mail"];
   values = [vCard org];
   max = [values count];
   if (max > 0)
     {
-      [fields setObject: [values objectAtIndex: 0] forKey: @"o"];
+      [fields setObject: [values objectAtIndex: 0] forKey: @"c_o"];
       if (max > 1)
-       [fields setObject: [values objectAtIndex: 1] forKey: @"ou"];
+       [fields setObject: [values objectAtIndex: 1] forKey: @"c_ou"];
     }
   adr = [vCard preferredAdr];
   if (adr)
-    [fields setObject: [adr value: 3] forKey: @"l"];
+    [fields setObject: [adr value: 3] forKey: @"c_l"];
   value = [[vCard uniqueChildWithTag: @"X-AIM"] value: 0];
-  [fields setObject: value forKey: @"screenname"];
+  [fields setObject: value forKey: @"c_screenname"];
 
   return fields;
 }
index 9a6188d199ab23c85bc9c3a6c4df196e6d3becbd..1c92971318c6a0eb682ee061531b6744630a2885 100644 (file)
@@ -105,30 +105,30 @@ static NSNumber *distantFutureNumber = nil;
 
   row = [NSMutableDictionary dictionaryWithCapacity:8];
 
-  [row setObject: @"vevent" forKey: @"component"];
+  [row setObject: @"vevent" forKey: @"c_component"];
  
   if ([uid isNotNull]) 
-    [row setObject:uid forKey: @"uid"];
+    [row setObject:uid forKey: @"c_uid"];
   else
     [self logWithFormat: @"WARNING: could not extract a uid from event!"];
 
 
   [row setObject: [NSNumber numberWithBool: isAllDay]
-       forKey: @"isallday"];
+       forKey: @"c_isallday"];
   [row setObject: [NSNumber numberWithBool: [_event isRecurrent]]
-       forKey: @"iscycle"];
+       forKey: @"c_iscycle"];
   [row setObject: [NSNumber numberWithBool: [_event isOpaque]]
-       forKey: @"isopaque"];
+       forKey: @"c_isopaque"];
   [row setObject: [NSNumber numberWithInt: [_event priorityNumber]]
-       forKey: @"priority"];
+       forKey: @"c_priority"];
 
-  if ([title isNotNull]) [row setObject: title forKey: @"title"];
-  if ([location isNotNull]) [row setObject: location forKey: @"location"];
-  if ([sequence isNotNull]) [row setObject: sequence forKey: @"sequence"];
+  if ([title isNotNull]) [row setObject: title forKey: @"c_title"];
+  if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
+  if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
 
   if ([startDate isNotNull])
     [row setObject: [self numberForDate: startDate]
-        forKey: @"startdate"];
+        forKey: @"c_startdate"];
   if ([endDate isNotNull])
     {
       if (endDate == distantFuture)
@@ -143,7 +143,7 @@ static NSNumber *distantFutureNumber = nil;
            = [NSNumber numberWithUnsignedInt:
                          [endDate timeIntervalSince1970] - i];
        }
-      [row setObject: dateNumber forKey: @"enddate"];
+      [row setObject: dateNumber forKey: @"c_enddate"];
     }
 
   if ([_event isRecurrent]) {
@@ -155,14 +155,14 @@ static NSNumber *distantFutureNumber = nil;
         more complex - thus we set it to a "reasonable" distant future */
       date = distantFuture;
     }
-    [row setObject:[self numberForDate:date] forKey: @"cycleenddate"];
-    [row setObject:[_event cycleInfo] forKey: @"cycleinfo"];
+    [row setObject:[self numberForDate:date] forKey: @"c_cycleenddate"];
+    [row setObject:[_event cycleInfo] forKey: @"c_cycleinfo"];
   }
 
   if ([participants length] > 0)
-    [row setObject: participants forKey: @"participants"];
+    [row setObject: participants forKey: @"c_participants"];
   if ([partmails length] > 0)
-    [row setObject: partmails forKey: @"partmails"];
+    [row setObject: partmails forKey: @"c_partmails"];
 
   if ([status isNotNull]) {
     int code = 1;
@@ -171,15 +171,15 @@ static NSNumber *distantFutureNumber = nil;
       code = 2;
     else if ([status isEqualToString: @"CANCELLED"])
       code = 0;
-    [row setObject:[NSNumber numberWithInt:code] forKey: @"status"];
+    [row setObject:[NSNumber numberWithInt:code] forKey: @"c_status"];
   }
   else {
     /* confirmed by default */
-    [row setObject: [NSNumber numberWithInt:1] forKey: @"status"];
+    [row setObject: [NSNumber numberWithInt:1] forKey: @"c_status"];
   }
 
   [row setObject: [NSNumber numberWithUnsignedInt: accessClass]
-       forKey: @"classification"];
+       forKey: @"c_classification"];
 
   organizer = [_event organizer];
   if (organizer) {
@@ -187,7 +187,7 @@ static NSNumber *distantFutureNumber = nil;
  
     email = [organizer valueForKey: @"rfc822Email"];
     if (email)
-      [row setObject:email forKey: @"orgmail"];
+      [row setObject:email forKey: @"c_orgmail"];
   }
  
   /* construct partstates */
@@ -203,7 +203,7 @@ static NSNumber *distantFutureNumber = nil;
       [partstates appendString: @"\n"];
     [partstates appendFormat: @"%d", stat];
   }
-  [row setObject:partstates forKey: @"partstates"];
+  [row setObject:partstates forKey: @"c_partstates"];
   [partstates release];
   return row;
 }
@@ -245,43 +245,43 @@ static NSNumber *distantFutureNumber = nil;
 
   row = [NSMutableDictionary dictionaryWithCapacity:8];
 
-  [row setObject: @"vtodo" forKey: @"component"];
+  [row setObject: @"vtodo" forKey: @"c_component"];
 
   if ([uid isNotNull]) 
-    [row setObject:uid forKey: @"uid"];
+    [row setObject:uid forKey: @"c_uid"];
   else
     [self logWithFormat: @"WARNING: could not extract a uid from event!"];
 
   [row setObject:[NSNumber numberWithBool:[_task isRecurrent]]
-       forKey: @"iscycle"];
+       forKey: @"c_iscycle"];
   [row setObject:[NSNumber numberWithInt:[_task priorityNumber]]
-       forKey: @"priority"];
+       forKey: @"c_priority"];
 
   [row setObject: [NSNumber numberWithBool: NO]
-       forKey: @"isallday"];
+       forKey: @"c_isallday"];
   [row setObject: [NSNumber numberWithBool: NO]
-       forKey: @"isopaque"];
+       forKey: @"c_isopaque"];
 
-  if ([title isNotNull]) [row setObject: title forKey: @"title"];
-  if ([location isNotNull]) [row setObject: location forKey: @"location"];
-  if ([sequence isNotNull]) [row setObject: sequence forKey: @"sequence"];
+  if ([title isNotNull]) [row setObject: title forKey: @"c_title"];
+  if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
+  if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
  
   if ([startDate isNotNull])
     date = [self numberForDate: startDate];
   else
     date = [NSNull null];
-  [row setObject: date forKey: @"startdate"];
+  [row setObject: date forKey: @"c_startdate"];
 
   if ([dueDate isNotNull]) 
     date = [self numberForDate: dueDate];
   else
     date = [NSNull null];
-  [row setObject: date forKey: @"enddate"];
+  [row setObject: date forKey: @"c_enddate"];
 
   if ([participants length] > 0)
-    [row setObject:participants forKey: @"participants"];
+    [row setObject:participants forKey: @"c_participants"];
   if ([partmails length] > 0)
-    [row setObject:partmails forKey: @"partmails"];
+    [row setObject:partmails forKey: @"c_partmails"];
 
   if ([status isNotNull]) {
     code = 0; /* NEEDS-ACTION */
@@ -291,15 +291,15 @@ static NSNumber *distantFutureNumber = nil;
       code = 2;
     else if ([status isEqualToString: @"CANCELLED"])
       code = 3;
-    [row setObject: [NSNumber numberWithInt: code] forKey: @"status"];
+    [row setObject: [NSNumber numberWithInt: code] forKey: @"c_status"];
   }
   else {
     /* confirmed by default */
-    [row setObject:[NSNumber numberWithInt:1] forKey: @"status"];
+    [row setObject:[NSNumber numberWithInt:1] forKey: @"c_status"];
   }
 
   [row setObject: [NSNumber numberWithUnsignedInt: accessClass]
-       forKey: @"classification"];
+       forKey: @"c_classification"];
 
   organizer = [_task organizer];
   if (organizer) {
@@ -307,7 +307,7 @@ static NSNumber *distantFutureNumber = nil;
  
     email = [organizer valueForKey: @"rfc822Email"];
     if (email)
-      [row setObject:email forKey: @"orgmail"];
+      [row setObject:email forKey: @"c_orgmail"];
   }
  
   /* construct partstates */
@@ -323,7 +323,7 @@ static NSNumber *distantFutureNumber = nil;
       [partstates appendString: @"\n"];
     [partstates appendFormat: @"%d", stat];
   }
-  [row setObject:partstates forKey: @"partstates"];
+  [row setObject:partstates forKey: @"c_partstates"];
   [partstates release];
   return row;
 }
index 0b6c1e7a33c03870d48565f2ac5ed7ae5bbe07d4..9f4ab50576cf027872c6626f739577a9f1586ffc 100644 (file)
       allowsNull = NO;
     },
     {
-      columnName = uid;
+      columnName = c_uid;
       sqlType    = "VARCHAR(256)";
       allowsNull = NO;
     },
     {
-      columnName = startdate;
+      columnName = c_startdate;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = enddate;
+      columnName = c_enddate;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = cycleenddate;
+      columnName = c_cycleenddate;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = title;
+      columnName = c_title;
       sqlType    = "VARCHAR(1000)";
       allowsNull = NO;
     },
     {
-      columnName = participants;
+      columnName = c_participants;
       sqlType    = "VARCHAR(1000000)";
       allowsNull = YES;
     },
     {
-      columnName = isallday;
+      columnName = c_isallday;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = iscycle;
+      columnName = c_iscycle;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = cycleinfo;
+      columnName = c_cycleinfo;
       sqlType    = "VARCHAR(1000)";
       allowsNull = YES;
     },
     {
-      columnName = classification;
+      columnName = c_classification;
       sqlType    = "INT";
       allowsNull = NO;
     },
     {
-      columnName = isopaque;
+      columnName = c_isopaque;
       sqlType    = "INT";
       allowsNull = NO;
     },
     {
-      columnName = status;
+      columnName = c_status;
       sqlType    = "INT";
       allowsNull = NO;
     },
     {
-      columnName = priority;
+      columnName = c_priority;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = location;
+      columnName = c_location;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = orgmail;
+      columnName = c_orgmail;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = partmails;
+      columnName = c_partmails;
       sqlType    = "VARCHAR(100000)";
       allowsNull = YES;
     },
     {
-      columnName = partstates;
+      columnName = c_partstates;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = sequence;
+      columnName = c_sequence;
       sqlType    = "INT";
       allowsNull = YES;
     },
     {
-      columnName = component;
+      columnName = c_component;
       sqlType    = "VARCHAR(10)";
       allowsNull = NO;
     },
index d1372447bff51913ab52abf3ef81f16d36ef9369..d51c6e704f87eee68a937bfb687a0733f39a4b7c 100644 (file)
       allowsNull = NO;
     },
     {
-      columnName = givenname;
+      columnName = c_givenname;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = cn;
+      columnName = c_cn;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = sn;
+      columnName = c_sn;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = screenname;
+      columnName = c_screenname;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = l;
+      columnName = c_l;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = mail;
+      columnName = c_mail;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = o;
+      columnName = c_o;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = ou;
+      columnName = c_ou;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
     {
-      columnName = telephoneNumber;
+      columnName = c_telephoneNumber;
       sqlType    = "VARCHAR(256)";
       allowsNull = YES;
     },
diff --git a/Scripts/sogo b/Scripts/sogo
deleted file mode 100755 (executable)
index 5514064..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#! /bin/sh
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-
-DAEMON=/usr/local/sbin/sogod-0.9
-NAME=sogo
-DESC="Scalable OpenGroupware.Org"
-
-PIDFILE=/var/run/sogo/sogod.pid
-
-SOGO_ARGS=""
-
-if [ -f /etc/default/sogo ]; then
-    . /etc/default/sogo
-fi
-
-test -x $DAEMON || exit 0
-
-#set -e
-
-case "$1" in
-  start)
-       echo -n "Starting $DESC: "
-       start-stop-daemon -c sogo --pidfile $PIDFILE \
-               -b --start --quiet --exec $DAEMON
-       echo "$NAME."
-       ;;
-  stop)
-       echo -n "Stopping $DESC: "
-       killall sogod-0.9 2> /dev/null
-       rm -f $PIDFILE
-       echo "$NAME."
-       ;;
-  restart|force-reload)
-       echo -n "Restarting $DESC: "
-       killall sogod-0.9 2> /dev/null
-       rm -f $PIDFILE
-       sleep 1
-       start-stop-daemon -c sogo --pidfile $PIDFILE \
-               -b --start --quiet --exec $DAEMON
-       echo "$NAME."
-       ;;
-  *)
-       N=/etc/init.d/$NAME
-       echo "Usage: $N {start|stop|restart|force-reload}" >&2
-       exit 1
-       ;;
-esac
-
-exit 0
index 2044a40abe7d33951e7d9855b1e1fbe8218b6e8a..db2a939b04a4f7ee4100524e06c4678c7e94fb50 100755 (executable)
@@ -1,5 +1,26 @@
 #! /bin/sh
 
+# SOGo init script for Debian GNU/Linux
+#
+# Copyright (C) 2007 Inverse groupe conseil
+#
+# Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This file 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
 
 DAEMON=/usr/sbin/sogod-0.9
index ad94d06bf8fcdefd9a983c4fe48cf8fc7c857c05..68ac60d78b23678ce7c15a4b07a475e9754026f6 100755 (executable)
@@ -1,5 +1,26 @@
 #!/bin/bash
+
+# SOGo init script for RedHat
+#
+# Copyright (C) 2007 Inverse groupe conseil
+#
+# Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
 #
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This file 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
 # sogod                Scalable OpenGroupware.org (Inverse edition)
 #
 # chkconfig:   - 85 15
index 99584cece982288647537ee99c86a5da70967b52..d2a326b2ac017a4e0f05e3fd7076bba6d6afdb02 100755 (executable)
@@ -1,9 +1,29 @@
 #!/bin/sh
 
+# SOGo daemon wrapper
+#
+# Copyright (C) 2007 Inverse groupe conseil
+#
+# Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This file 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
 PIDFILE=/var/run/sogo/sogod.pid
 
 . /usr/lib/GNUstep/System/Library/Makefiles/GNUstep.sh
 
 echo $$ > $PIDFILE
 exec $GNUSTEP_LOCAL_ROOT/Tools/sogod-0.9 >& /var/log/sogo/sogod.log
-
diff --git a/Scripts/sql-update-20070724.sh b/Scripts/sql-update-20070724.sh
new file mode 100755 (executable)
index 0000000..65bd689
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# this script only work with PostgreSQL, which at this time is the only
+# database really supported by SOGo/SOPE
+
+defaultusername=$USER
+defaulthostname=localhost
+defaultdatabase=$USER
+
+read -p "Username ($defaultusername): " username
+read -p "Hostname ($defaulthostname): " hostname
+read -p "Database ($defaultdatabase): " database
+
+if [ -z "$username" ]
+then
+  username=$defaultusername
+fi
+if [ -z "$hostname" ]
+then
+  hostname=$defaulthostname
+fi
+if [ -z "$database" ]
+then
+  database=$defaultdatabase
+fi
+
+echo ""
+echo "You will now be requested your password thrice..."
+echo "After that, a list of SQL operations will scroll."
+echo ""
+
+sqlscript=""
+
+function renameFields() {
+    oldIFS="$IFS"
+    IFS=" "
+    set $fields
+    for field in $@
+    do
+       part="`echo -e \"ALTER TABLE $table RENAME $field TO c_${field};\\n\"`";
+       sqlscript="$sqlscript$part"
+    done
+    IFS="$oldIFS"
+}
+
+table=sogo_user_profile
+fields="uid defaults settings"
+renameFields
+
+fields="uid startdate enddate cycleenddate title cycleinfo participants isallday iscycle classification status priority isopaque location orgmail partmails partstates sequence component"
+tables=`psql -U $username -h $hostname $database -c "select split_part(c_quick_location, '/', 5) from sogo_folder_info where c_folder_type ilike 'Appointment';" | grep _quick`
+for table in $tables;
+do
+  renameFields
+done
+
+fields="givenname cn sn l mail o ou telephonenumber screenname"
+tables=`psql -U $username -h $hostname $database -c "select split_part(c_quick_location, '/', 5) from sogo_folder_info where c_folder_type ilike 'Contact';" | grep _quick`
+for table in $tables;
+do
+  renameFields
+done
+
+sqlscript="$sqlscript;"
+echo "$sqlscript" | psql -e -U $username -h $hostname $database
index 8cc9c45d2e570853b6c1b3be70a6f30f1391d7ad..af7370d550260825416dd21518646d28f878126f 100644 (file)
@@ -143,7 +143,7 @@ static NSNumber   *sharedYes = nil;
 
   c_name = [object objectForKey: @"c_name"];
 
-  if ([[object objectForKey: @"component"] isEqualToString: @"vevent"])
+  if ([[object objectForKey: @"c_component"] isEqualToString: @"vevent"])
     componentClass = [SOGoAppointmentObject class];
   else
     componentClass = [SOGoTaskObject class];
@@ -497,12 +497,12 @@ static NSNumber   *sharedYes = nil;
   Class objectClass;
 
   qualifier = [EOQualifier qualifierWithQualifierFormat:@"c_name = %@", c_name];
-  records = [[self ocsFolder] fetchFields: [NSArray arrayWithObject: @"component"]
+  records = [[self ocsFolder] fetchFields: [NSArray arrayWithObject: @"c_component"]
                               matchingQualifier: qualifier];
 
   if ([records count])
     {
-      component = [[records objectAtIndex:0] valueForKey: @"component"];
+      component = [[records objectAtIndex:0] valueForKey: @"c_component"];
       if ([component isEqualToString: @"vevent"])
         objectClass = [SOGoAppointmentObject class];
       else if ([component isEqualToString: @"vtodo"])
@@ -526,7 +526,7 @@ static NSNumber   *sharedYes = nil;
   
   md = [[_record mutableCopy] autorelease];
  
-  if ((tmp = [_record objectForKey:@"startdate"])) {
+  if ((tmp = [_record objectForKey:@"c_startdate"])) {
     tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
           (NSTimeInterval)[tmp unsignedIntValue]];
     [tmp setTimeZone: timeZone];
@@ -536,7 +536,7 @@ static NSNumber   *sharedYes = nil;
   else
     [self logWithFormat:@"missing 'startdate' in record?"];
 
-  if ((tmp = [_record objectForKey:@"enddate"])) {
+  if ((tmp = [_record objectForKey:@"c_enddate"])) {
     tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
           (NSTimeInterval)[tmp unsignedIntValue]];
     [tmp setTimeZone: timeZone];
@@ -605,23 +605,23 @@ static NSNumber   *sharedYes = nil;
   NSArray             *rules, *exRules, *exDates, *ranges;
   unsigned            i, count;
 
-  cycleinfo  = [[_row objectForKey:@"cycleinfo"] propertyList];
+  cycleinfo  = [[_row objectForKey:@"c_cycleinfo"] propertyList];
   if (cycleinfo == nil) {
     [self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@", _row];
     return;
   }
 
   row = [self fixupRecord:_row fetchRange: _r];
-  [row removeObjectForKey:@"cycleinfo"];
-  [row setObject:sharedYes forKey:@"isRecurrentEvent"];
+  [row removeObjectForKey: @"c_cycleinfo"];
+  [row setObject: sharedYes forKey:@"isRecurrentEvent"];
 
-  startDate = [row objectForKey:@"startDate"];
-  endDate   = [row objectForKey:@"endDate"];
+  startDate = [row objectForKey:@"c_startDate"];
+  endDate   = [row objectForKey:@"c_endDate"];
   fir       = [NGCalendarDateRange calendarDateRangeWithStartDate:startDate
                                    endDate:endDate];
-  rules     = [cycleinfo objectForKey:@"rules"];
-  exRules   = [cycleinfo objectForKey:@"exRules"];
-  exDates   = [cycleinfo objectForKey:@"exDates"];
+  rules     = [cycleinfo objectForKey:@"c_rules"];
+  exRules   = [cycleinfo objectForKey:@"c_exRules"];
+  exDates   = [cycleinfo objectForKey:@"c_exDates"];
 
   ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange:_r
                                      firstInstanceCalendarDateRange:fir
@@ -673,8 +673,8 @@ static NSNumber   *sharedYes = nil;
         components = [NSArray arrayWithObject: _component];
 
       sqlString
-        = [NSString stringWithFormat: @" AND (component = '%@')",
-                    [components componentsJoinedByString: @"' OR component = '"]];
+        = [NSString stringWithFormat: @" AND (c_component = '%@')",
+                    [components componentsJoinedByString: @"' OR c_component = '"]];
     }
   else
     sqlString = @"";
@@ -691,7 +691,7 @@ static NSNumber   *sharedYes = nil;
   end = (unsigned int) [_endDate timeIntervalSince1970];
 
   return [NSString stringWithFormat:
-                     @" AND (startdate <= %u) AND (enddate >= %u)",
+                     @" AND (c_startdate <= %u) AND (c_enddate >= %u)",
                    end, start];
 }
 
@@ -809,14 +809,14 @@ static NSNumber   *sharedYes = nil;
   /* prepare mandatory fields */
 
   fields = [NSMutableArray arrayWithArray: _fields];
-  [fields addObject: @"uid"];
-  [fields addObject: @"startdate"];
-  [fields addObject: @"enddate"];
+  [fields addObject: @"c_uid"];
+  [fields addObject: @"c_startdate"];
+  [fields addObject: @"c_enddate"];
 
   if (logger)
     [self debugWithFormat:@"should fetch (%@=>%@) ...", _startDate, _endDate];
 
-  sql = [NSString stringWithFormat: @"(iscycle = 0)%@%@%@",
+  sql = [NSString stringWithFormat: @"(c_iscycle = 0)%@%@%@",
                   dateSqlString, componentSqlString, privacySqlString];
 
   /* fetch non-recurrent apts first */
@@ -834,11 +834,11 @@ static NSNumber   *sharedYes = nil;
     }
 
   /* fetch recurrent apts now */
-  sql = [NSString stringWithFormat: @"(iscycle = 1)%@%@%@",
+  sql = [NSString stringWithFormat: @"(c_iscycle = 1)%@%@%@",
                   dateSqlString, componentSqlString, privacySqlString];
   qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
 
-  [fields addObject: @"cycleinfo"];
+  [fields addObject: @"c_cycleinfo"];
 
   records = [_folder fetchFields: fields matchingQualifier: qualifier];
   if (records)
@@ -895,8 +895,8 @@ static NSNumber   *sharedYes = nil;
   static NSArray *infos = nil; // TODO: move to a plist file
   
   if (!infos)
-    infos = [[NSArray alloc] initWithObjects: @"partmails", @"partstates",
-                             @"isopaque", @"status", nil];
+    infos = [[NSArray alloc] initWithObjects: @"c_partmails", @"c_partstates",
+                             @"c_isopaque", @"c_status", nil];
 
   return [self fetchFields: infos from: _startDate to: _endDate
                component: @"vevent"];
@@ -910,12 +910,13 @@ static NSNumber   *sharedYes = nil;
 
   if (!infos)
     infos = [[NSArray alloc] initWithObjects:
-                               @"c_name", @"component",
-                             @"title", @"location", @"orgmail",
-                             @"status", @"classification",
-                             @"isallday", @"isopaque",
-                             @"participants", @"partmails",
-                             @"partstates", @"sequence", @"priority", nil];
+                               @"c_name", @"c_component",
+                             @"c_title", @"c_location", @"c_orgmail",
+                             @"c_status", @"c_classification",
+                             @"c_isallday", @"c_isopaque",
+                             @"c_participants", @"c_partmails",
+                             @"c_partstates", @"c_sequence", @"c_priority",
+                            nil];
 
   return [self fetchFields: infos from: _startDate to: _endDate
                component: _component];
index df3f08341a660759f73104ff962d88568d6f95ab..23444abd78860f6a84a98d277af3f6471a4e5cc3 100644 (file)
@@ -33,9 +33,9 @@
 #import "SOGoContactGCSEntry.h"
 #import "SOGoContactGCSFolder.h"
 
-#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
-                                     @"givenname", @"screenname", \
-                                    @"o", @"mail", @"telephonenumber", \
+#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"c_cn", \
+                                     @"c_givenname", @"c_screenname", \
+                                    @"c_o", @"c_mail", @"c_telephonenumber", \
                                      nil]
 
 @implementation SOGoContactGCSFolder
   if (filter && [filter length] > 0)
     {
       qs = [NSString stringWithFormat:
-                       @"(sn isCaseInsensitiveLike: '%@%%') OR "
-                     @"(givenname isCaseInsensitiveLike: '%@%%') OR "
-                     @"(mail isCaseInsensitiveLike: '%@%%') OR "
-                     @"(telephonenumber isCaseInsensitiveLike: '%%%@%%')",
+                       @"(c_sn isCaseInsensitiveLike: '%@%%') OR "
+                     @"(c_givenname isCaseInsensitiveLike: '%@%%') OR "
+                     @"(c_mail isCaseInsensitiveLike: '%@%%') OR "
+                     @"(c_telephonenumber isCaseInsensitiveLike: '%%%@%%')",
                      filter, filter, filter, filter];
       qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
     }
   return qualifier;
 }
 
+- (NSArray *) _flattenedRecords: (NSArray *) records
+{
+  NSMutableArray *newRecords;
+  NSEnumerator *oldRecords;
+  NSDictionary *oldRecord;
+  NSMutableDictionary *newRecord;
+  NSString *data;
+  
+  newRecords = [NSMutableArray arrayWithCapacity: [records count]];
+
+  oldRecords = [records objectEnumerator];
+  oldRecord = [oldRecords nextObject];
+  while (oldRecord)
+    {
+      newRecord = [NSMutableDictionary new];
+      [newRecord autorelease];
+
+      [newRecord setObject: [oldRecord objectForKey: @"c_name"]
+                forKey: @"c_uid"];
+      [newRecord setObject: [oldRecord objectForKey: @"c_name"]
+                forKey: @"c_name"];
+
+      data = [oldRecord objectForKey: @"c_cn"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data
+                forKey: @"displayName"];
+
+      data = [oldRecord objectForKey: @"c_mail"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"mail"];
+
+      data = [oldRecord objectForKey: @"c_screenname"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"screenName"];
+
+      data = [oldRecord objectForKey: @"c_o"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"org"];
+
+      data = [oldRecord objectForKey: @"c_telephonenumber"];
+      if (![data length])
+       data = @"";
+      [newRecord setObject: data forKey: @"phone"];
+
+      [newRecords addObject: newRecord];
+      oldRecord = [oldRecords nextObject];
+    }
+
+  return newRecords;
+}
+
 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
                                 sortBy: (NSString *) sortKey
                               ordering: (NSComparisonResult) sortOrdering
 {
-  NSArray *fields, *records;
+  NSArray *fields, *dbRecords, *records;
   EOQualifier *qualifier;
   EOSortOrdering *ordering;
 
 
   fields = folderListingFields;
   qualifier = [self _qualifierForFilter: filter];
-  records = [[self ocsFolder] fetchFields: fields
-                             matchingQualifier: qualifier];
-  if ([records count] > 1)
+  dbRecords = [[self ocsFolder] fetchFields: fields
+                               matchingQualifier: qualifier];
+  if ([dbRecords count] > 1)
     {
+      records = [self _flattenedRecords: dbRecords];
       ordering
         = [EOSortOrdering sortOrderingWithKey: sortKey
                           selector: ((sortOrdering == NSOrderedDescending)
                      [NSArray arrayWithObject: ordering]];
     }
   else
-    [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
+    records = nil;
+//   else
+//     [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
 
   //[self debugWithFormat:@"fetched %i records.", [records count]];
   return records;
index 60e4ee98834fcd76543b42ddb9344d33ec00a53a..2704be3321abfd684d775400a5d9cf23ce2fe24f 100644 (file)
 #import "SOGoContactLDIFEntry.h"
 #import "SOGoContactLDAPFolder.h"
 
-#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
-                                     @"displayName",                     \
-                                     @"streetAddress",                   \
-                                     @"o", \
-                                     @"sn", @"givenname", @"l",          \
-                                     @"mail", @"telephonenumber",        \
-                                     @"mailNickname",                    \
-                                     @"sAMAccountName",                  \
-                                     @"uid",                  \
-                                     nil]
-
 @class WOContext;
 
 @implementation SOGoContactLDAPFolder
   return keys;
 }
 
+- (NSArray *) _flattenedRecords: (NSArray *) records
+{
+  NSMutableArray *newRecords;
+  NSEnumerator *oldRecords;
+  NSDictionary *oldRecord;
+  NSMutableDictionary *newRecord;
+  NSString *data;
+  
+  newRecords = [[NSMutableArray alloc] initWithCapacity: [records count]];
+  [newRecords autorelease];
+
+  oldRecords = [records objectEnumerator];
+  oldRecord = [oldRecords nextObject];
+  while (oldRecord)
+    {
+      newRecord = [NSMutableDictionary new];
+      [newRecord autorelease];
+
+      [newRecord setObject: [oldRecord objectForKey: @"c_uid"]
+                forKey: @"c_uid"];
+      [newRecord setObject: [oldRecord objectForKey: @"c_name"]
+                forKey: @"c_name"];
+
+      data = [oldRecord objectForKey: @"displayName"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data
+                forKey: @"displayName"];
+
+      data = [oldRecord objectForKey: @"mail"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"mail"];
+
+      data = [oldRecord objectForKey: @"nsAIMid"];
+      if (![data length])
+       data = [oldRecord objectForKey: @"nscpaimscreenname"];
+      if (![data length])
+       data = @"";
+      [newRecord setObject: data forKey: @"screenName"];
+
+      data = [oldRecord objectForKey: @"o"];
+      if (!data)
+       data = @"";
+      [newRecord setObject: data forKey: @"org"];
+
+      data = [oldRecord objectForKey: @"telephoneNumber"];
+      if (![data length])
+       data = [oldRecord objectForKey: @"cellphone"];
+      if (![data length])
+       data = [oldRecord objectForKey: @"homePhone"];
+      if (![data length])
+       data = @"";
+      [newRecord setObject: data forKey: @"phone"];
+
+      [newRecords addObject: newRecord];
+      oldRecord = [oldRecords nextObject];
+    }
+
+  return newRecords;
+}
+
 - (NSArray *) lookupContactsWithFilter: (NSString *) filter
                                 sortBy: (NSString *) sortKey
                               ordering: (NSComparisonResult) sortOrdering
 
   if (filter && [filter length] > 0)
     {
-      records = [ldapSource fetchContactsMatching: filter];
+      records = [self _flattenedRecords:
+                       [ldapSource fetchContactsMatching: filter]];
       ordering
         = [EOSortOrdering sortOrderingWithKey: sortKey
                           selector: ((sortOrdering == NSOrderedDescending)
                      [NSArray arrayWithObject: ordering]];
     }
 
-  //[self debugWithFormat:@"fetched %i records.", [records count]];
   return result;
 }
 
index 10b88155e9e7863389012ae0b51d7f70af954d9e..15743275f8b18aec223d748144ec8d0acb6039b7 100644 (file)
@@ -38,7 +38,7 @@
 
 @implementation AgenorUserDefaults
 
-static NSString *uidColumnName = @"uid";
+static NSString *uidColumnName = @"c_uid";
 
 - (id) initWithTableURL: (NSURL *) tableURL
                    uid: (NSString *) userID
index 75fe64d40586ed942c6bfa670e429b819f3ed1d7..eeb0a14afb043414fc6b07c217fa138df5b8d54c 100644 (file)
 #import "LDAPSource.h"
 
 static NSArray *commonSearchFields;
+static int timeLimit;
+static int sizeLimit;
 
 @implementation LDAPSource
 
 + (void) initialize
 {
+  NSUserDefaults *ud;
+
   if (!commonSearchFields)
     {
+      ud = [NSUserDefaults standardUserDefaults];
+      sizeLimit = [ud integerForKey: @"SOGoLDAPQueryLimit"];
+      timeLimit = [ud integerForKey: @"SOGoLDAPQueryTimeout"];
+
       commonSearchFields = [NSArray arrayWithObjects:
                                      @"title",
                                    @"company",
@@ -211,6 +219,10 @@ static NSArray *commonSearchFields;
   [ldapConnection bindWithMethod: @"simple"
                  binddn: bindDN
                  credentials: password];
+  if (sizeLimit > 0)
+    [ldapConnection setQuerySizeLimit: sizeLimit];
+  if (timeLimit > 0)
+    [ldapConnection setQueryTimeLimit: timeLimit];
 }
 
 /* user management */
@@ -264,6 +276,8 @@ static NSArray *commonSearchFields;
     {
       bindConnection = [[NGLdapConnection alloc] initWithHostName: hostname
                                                 port: port];
+      if (timeLimit > 0)
+       [ldapConnection setQueryTimeLimit: timeLimit];
       if (bindFields)
        userDN = [self _fetchUserDNForLogin: loginToCheck];
       else
index 00d9b3f3eb79cc260a4028ac5dbc32a7cd90b452..d212d2c1e48686864bed1f7db824016f7ea40d96 100644 (file)
@@ -296,7 +296,7 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
     userDefaults
       = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
                                    uid: login
-                                   fieldName: @"defaults"];
+                                   fieldName: @"c_defaults"];
 
   return userDefaults;
 }
@@ -307,7 +307,7 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
     userSettings
       = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
                                    uid: login
-                                   fieldName: @"settings"];
+                                   fieldName: @"c_settings"];
 
   return userSettings;
 }
index 4803bba0ea6a575763ff184382da80d55ec2df57..940cbaa55d58c17fa91e31e57f9d246aeda09418 100644 (file)
 
 - (NSString *) defaultSortKey
 {
-  return @"fn";
-}
-
-- (NSString *) displayName
-{
-  NSString *displayName;
-
-  displayName = [currentContact objectForKey: @"displayName"];
-  if (!(displayName && [displayName length] > 0))
-    displayName = [currentContact objectForKey: @"cn"];
-
-  return displayName;
+  return @"displayName";
 }
 
 - (NSString *) sortKey
       else
        valueText = nil;
 
-      ASSIGN (contactInfos,
-             [folder lookupContactsWithFilter: valueText
-                     sortBy: [self sortKey]
-                     ordering: ordering]);
+      [contactInfos release];
+      contactInfos = [folder lookupContactsWithFilter: valueText
+                            sortBy: [self sortKey]
+                            ordering: ordering];
+      [contactInfos retain];
     }
 
   return contactInfos;
index 2012e7dda470a19c25e2c45e45cd7cc8728e68d6..1849425b8ae633d01023699353e5321f9c55b417 100644 (file)
@@ -4,7 +4,7 @@
 --
 
 CREATE TABLE SOGo_user_profile (
-  uid      VARCHAR(255) NOT NULL PRIMARY KEY,
-  defaults TEXT,
-  settings TEXT
+  c_uid      VARCHAR(255) NOT NULL PRIMARY KEY,
+  c_defaults TEXT,
+  c_settings TEXT
 );
index bcbb66bcd78c9b33931361bd4d20ea11581f53e5..03f647f9dac358538a0ac0d17248e10a9bc2613d 100644 (file)
                       forUser: userLogin];
   if ([roleString isEqualToString: @"ComponentDAndTViewer"])
     {
-      [component setObject: @"" forKey: @"title"];
-      [component setObject: @"" forKey: @"location"];
+      [component setObject: @"" forKey: @"c_title"];
+      [component setObject: @"" forKey: @"c_location"];
     }
 }
 
       newInfo = [currentInfos nextObject];
       while (newInfo)
        {
-         uid = [newInfo objectForKey: @"uid"];
+         uid = [newInfo objectForKey: @"c_uid"];
          currentInfo = [infos objectForKey: uid];
          if (!currentInfo
              || [owner isEqualToString: userLogin])
            {
              [self _updatePrivacyInComponent: newInfo
                    fromFolder: currentFolder];
-             [newInfo setObject: owner forKey: @"owner"];
+             [newInfo setObject: owner forKey: @"c_owner"];
              [infos setObject: [newInfo objectsForKeys: fields
                                         notFoundMarker: marker]
                     forKey: uid];
   [self _setupContext];
 
   newEvents = [NSMutableArray array];
-  fields = [NSArray arrayWithObjects: @"c_name", @"owner", @"status",
-                   @"title", @"startdate", @"enddate", @"location",
-                   @"isallday", nil];
+  fields = [NSArray arrayWithObjects: @"c_name", @"c_owner", @"c_status",
+                   @"c_title", @"c_startdate", @"c_enddate", @"c_location",
+                   @"c_isallday", nil];
   events = [[self _fetchFields: fields
                  forComponentOfType: @"vevent"] objectEnumerator];
   oldEvent = [events nextObject];
 
   [self _setupContext];
 
-  fields = [NSArray arrayWithObjects: @"c_name", @"owner", @"status",
-                   @"title", @"enddate", nil];
+  fields = [NSArray arrayWithObjects: @"c_name", @"c_owner", @"c_status",
+                   @"c_title", @"c_enddate", nil];
 
   tasks = [[self _fetchFields: fields
                 forComponentOfType: @"vtodo"] objectEnumerator];
index 7d4836e5c743adec3abad4dfb66b9cc3f9018991..79df8ddf77b513d1272e13d051fe794d5f95593e 100644 (file)
             ondblclick="return onContactRowDblClick(event, this);"
             oncontextmenu="return onContactContextMenu(event, this);">
             <td><img rsrc:src="abcard.gif"
-               /><var:string value="displayName" const:escapeHTML="YES" /></td>
+               /><var:string value="currentContact.displayName" const:escapeHTML="YES" /></td>
             <td><var:string value="currentContact.mail"/></td>
-            <td><var:string value="currentContact.screenname"/></td>
-            <td><var:string value="currentContact.o"/></td>
-            <td><var:string value="currentContact.telephonenumber"/></td>
+            <td><var:string value="currentContact.screenName"/></td>
+            <td><var:string value="currentContact.org"/></td>
+            <td><var:string value="currentContact.phone"/></td>
           </tr>
         </var:foreach>
       </tbody>