#import <Foundation/Foundation.h>
#import <EOAccess/EOAccess.h>
#include <NGExtensions/NGExtensions.h>

int main(int argc, char **argv, char **env) {
  EOModel          *m = nil;
  EOAdaptor        *a;
  EOAdaptorContext *ctx;
  EOAdaptorChannel *ch;
  NSDictionary     *conDict;
  NSString         *expr;
  
  [NSProcessInfo initializeWithArguments:argv count:argc environment:env];

  NS_DURING {
  
  conDict = [NSDictionary dictionaryWithContentsOfFile:@"condict.plist"];
  NSLog(@"condict is %@", conDict);
  
  if ((a = [EOAdaptor adaptorWithName:@"PostgreSQL"]) == nil) {
    NSLog(@"found no PostgreSQL adaptor ..");
    exit(1);
  }
  
  NSLog(@"got adaptor %@", a);
  [a setConnectionDictionary:conDict];
  NSLog(@"got adaptor with condict %@", a);
  
  ctx = [a   createAdaptorContext];
  ch  = [ctx createAdaptorChannel];

#if 1
  m = AUTORELEASE([[EOModel alloc] initWithContentsOfFile:@"test.eomodel"]);
  if (m) {
    [a setModel:m];
    [a setConnectionDictionary:conDict];
  }
#endif
  
  expr = [[NSUserDefaults standardUserDefaults] stringForKey:@"sql"];

  NSLog(@"opening channel ..");

  [ch setDebugEnabled:YES];
  
  if ([ch openChannel]) {
    NSLog(@"channel is open");
    
    if ([ctx beginTransaction]) {
      NSLog(@"began tx ..");

      /* do something */
      {
        NSAutoreleasePool *pool = [NSAutoreleasePool new];
        EOEntity *e;
        EOSQLQualifier *q;
        NSArray *attrs;

#if 1
        /* fetch some expr */

        if (expr) {
          if ([ch evaluateExpression:expr]) {
            NSDictionary *record;

            attrs = [ch describeResults];
            NSLog(@"results: %@", attrs);
	    
            while ((record = [ch fetchAttributes:attrs withZone:nil]))
              NSLog(@"fetched %@", record);
          }
        }
#endif
        /* fetch some doof records */

        e = [m entityNamed:@"Doof"];
        NSLog(@"entity: %@", e);
        if (e == nil)
          exit(1);
        
        q = [e qualifier];
        attrs = [e attributes];

        if ([ch selectAttributes:attrs
                describedByQualifier:q
                fetchOrder:nil
                lock:NO]) {
          NSDictionary *record;

          while ((record = [ch fetchAttributes:attrs withZone:nil])) {
            NSLog(@"fetched %@ birthday %@",
                  [record valueForKey:@"pkey"],
                  [record valueForKey:@"companyId"]);
          }
        }
        else
          NSLog(@"Could not select ..");

        /* fetch some team records */

        if ((e = [m entityNamed:@"Team"])) {
          q = [e qualifier];
          attrs = [e attributes];

          if ([ch selectAttributes:attrs
                  describedByQualifier:q
                  fetchOrder:nil
                  lock:NO]) {
            NSDictionary *record;

            while ((record = [ch fetchAttributes:attrs withZone:nil])) {
              NSLog(@"fetched %@ birthday %@",
                    [record valueForKey:@"description"],
                    [record valueForKey:@"companyId"]);
            }
          }
          else
            NSLog(@"Could not select ..");
        }
        
        /* do some update */

        if ((e = [m entityNamed:@"Person"])) {
          attrs = [e attributes];
          q = [[EOSQLQualifier alloc]
                               initWithEntity:e
                               qualifierFormat:@"%A='helge'", @"login"];
          AUTORELEASE(q);

          if ([ch selectAttributes:attrs
                  describedByQualifier:q
                  fetchOrder:nil
                  lock:NO]) {
            NSDictionary *record;

            record = [ch fetchAttributes:attrs withZone:nil];
          }
          else
            NSLog(@"Could not select ..");
        }

        RELEASE(pool);
      }
      
      NSLog(@"committing tx ..");
      if ([ctx commitTransaction])
        NSLog(@"  could commit.");
      else
        NSLog(@"  commit failed.");
    }
    
    NSLog(@"closing channel ..");
    [ch closeChannel];
  }
  }
  NS_HANDLER {
    fprintf(stderr, "exception: %s\n", [[localException description] cString]);
    abort();
  }
  NS_ENDHANDLER;

  return 0;
}
