Commits

Tuukka Norri committed 9238d15

Query logging and one-to-one relationships
- One-to-one relationships should now be updateable even with views (references #7).
- Changed query logging so that query parameters are visible in the log.
- Added some helper methods which proved to be unnecessary at the moment.
- Added rules to views in the test database.

  • Participants
  • Parent commits dc6ce6f
  • Branches PGTS

Comments (0)

Files changed (9)

Dependencies/TSDataTypes/Sources/TSIndexDictionary.h

 - (unsigned int *) indexVectorSortedByValue;
 - (unsigned int *) indexVectorSortedByValueUsingFunction: (int (*)(const void *, const void *)) compar;
 - (void) makeObjectsPerformSelector: (SEL) aSelector withObject: (id) anObject;
+- (unsigned int) indexOfObject: (id) anObject;
 
 @end
 

Dependencies/TSDataTypes/Sources/TSIndexDictionary.m

     return NSAllMapTableValues (map);
 }
 
+- (unsigned int) indexOfObject: (id) anObject
+{
+    TSIndexEnumerator* e = [self indexEnumerator];
+    unsigned int currentIndex = 0;
+    while (NSNotFound != (currentIndex = [e nextIndex]))
+    {
+        if ([[self objectAtIndex: currentIndex] isEqual: anObject])
+            break;
+    }
+    return currentIndex;
+}
 @end

Framework/Sources/PGTSConnectionDelegate.h

 //
 
 #import <PGTS/PGTSConstants.h>
+#import <PGTS/postgresql/libpq-fe.h>
 
 /** See PGTSConstants.h */
 /** See PGTSConstants.m */
 
 /** Formal part of the protocol */
 @protocol PGTSConnectionDelegate <NSObject>
+@end
+
+
+@interface NSObject (PGTSNotifierDelegate)
+- (BOOL) PGTSNotifierShouldHandleNotification: (NSNotification *) notification fromTableWithOid: (Oid) oid;
 @end

Framework/Sources/PGTSConnectionPrivate.h

 #define kPGTSRaiseForReceiveCopyData    (1 << 5)
 #define kPGTSRaiseForSendCopyData       (1 << 6)
     
-#define LogQuery(...) { if (YES == logsQueries) [self logQuery: __VA_ARGS__]; }
+#define LogQuery( QUERY, PARAMETERS ) { if (YES == logsQueries) [self logQuery: QUERY parameters: PARAMETERS]; }
 
 
 @interface PGTSConnection (PrivateMethods)
 - (void) workerThreadMain: (NSLock *) threadLock;
 - (BOOL) workerPollConnectionResetting: (BOOL) reset;
 - (void) workerEnd;
-- (void) logQuery: (id) format, ...;
+- (void) logQuery: (NSString *) query parameters: (NSArray *) parameters;
 - (void) logNotice: (id) anObject;
 - (void) logNotification: (id) anObject;
 - (void) postPGnotifications;

Framework/Sources/PGTSConnectionPrivate.m

         
         if (YES == rval && CONNECTION_OK == connectionStatus)
         {
-            LogQuery (@"Connected to backend %d", [self backendPID]);
             PQsetnonblocking (connection, 0); //We don't want to call PQsendquery etc. multiple times
             PQsetClientEncoding (connection, "UNICODE"); //Use UTF-8
             //FIXME: set other things, such as the date format, as well
     NSLog (@"workerEnd");
 }
 
-- (void) logQuery: (id) format, ...
+- (void) logQuery: (NSString *) query parameters: (NSArray *) parameters
 {
-    va_list ap; 
-    va_start (ap, format);
-    fprintf (stdout, "(%p) ", self);
-    vfprintf (stdout, [[format description] UTF8String], ap);
-    fprintf (stdout, "\n");
-    va_end (ap);
+    fprintf (stdout, "(%p) %s %s\n", self, [[query description] UTF8String], [[parameters description] UTF8String]);
 }
 
 - (void) logNotice: (id) anObject

Framework/Sources/PGTSConnectionQueries.m

 - (int) sendQuery2: (NSString *) queryString messageDelegate: (BOOL) messageDelegate
 {
     int rval = 0;
-    LogQuery (queryString);
+    LogQuery (queryString, nil);
     [connectionLock lock];
     SendQuery (rval = PQsendQuery (connection, [queryString UTF8String]));
     [connectionLock unlock];
 		}
     }
     
-    LogQuery (queryString);
+    LogQuery (queryString, parameters);
     [connectionLock lock];
     SendQuery (rval = PQsendQueryParams (connection, [queryString UTF8String], nParams, paramTypes,
                                   paramValues, paramLengths, paramFormats, 0));
         //paramFormats [i] = (0 == length ? 0 : 1);
     }
     
-    LogQuery (aName);
+    LogQuery (aName, arguments);
     [connectionLock lock];
     SendQuery (rval = PQsendQueryPrepared (connection, [aName UTF8String], nParams, paramValues, 
                                     (const int *) paramLengths, (const int *) paramFormats, 0));

Framework/Sources/PGTSModificationNotifier.m

 
 - (void) handleNotification: (NSNotification *) notification
 {
-    NSAssert (nil != connection, nil);
-    NSDictionary* userInfo = [notification userInfo];
-    NSNumber* backendPID = [NSNumber numberWithInt: [connection backendPID]];
-    if (observesSelfGenerated || NO == [[userInfo objectForKey: kPGTSBackendPIDKey] isEqualToNumber: backendPID])
+    if ([self shouldHandleNotification: notification])
     {
+        NSAssert (nil != connection, nil);
         [self checkInModificationTableNamed: [notification name]];
     }
 }

Framework/Sources/PGTSNotifier.h

     NSDate* lastCheck;
     BOOL observesSelfGenerated;
     NSArray* sentNotifications;
+    id delegate;
 }
 
 - (BOOL) addObserver: (id) anObject selector: (SEL) aSelector table: (PGTSTableInfo *) tableInfo 
 - (PGTSConnection *) connection;
 - (void) setConnection: (PGTSConnection *) aConnection;
 
+- (BOOL) shouldHandleNotification: (NSNotification *) notification;
+- (void) setDelegate: (id) anObject;
+
 @end

Framework/Sources/PGTSNotifier.m

 #import "PGTSConstants.h"
 #import "PGTSTableInfo.h"
 #import "PGTSDatabaseInfo.h"
+#import "PGTSConnectionDelegate.h"
 
 
 //FIXME: change this so that being connection specific is actually enforced
     }
 }
 
+- (BOOL) shouldHandleNotification: (NSNotification *) notification
+{
+    BOOL rval = NO;
+    if (nil == delegate)
+    {
+        NSDictionary* userInfo = [notification userInfo];
+        NSNumber* backendPID = [NSNumber numberWithInt: [connection backendPID]];
+        if (observesSelfGenerated || NO == [[userInfo objectForKey: kPGTSBackendPIDKey] isEqualToNumber: backendPID])
+            rval = YES;
+    }
+    else
+    {
+        rval = [delegate PGTSNotifierShouldHandleNotification: notification
+                                             fromTableWithOid: [notificationNames indexOfObject: [notification name]]];
+    }
+    return rval;
+}
+
+- (void) setDelegate: (id) anObject
+{
+    delegate = anObject; 
+}
+
 @end