- order queried events by event_id
[plcapi.git] / Shell.py
index 8d454e0..a649e84 100755 (executable)
--- a/Shell.py
+++ b/Shell.py
@@ -5,7 +5,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2005 The Trustees of Princeton University
 #
-# $Id: Shell.py,v 1.9 2006/10/27 15:26:44 mlhuang Exp $
+# $Id: Shell.py,v 1.12 2006/11/02 22:07:22 mlhuang Exp $
 #
 
 import os, sys
@@ -33,11 +33,10 @@ method = None
 user = None
 password = None
 role = None
+xmlrpc = False
 
-if not os.path.exists(sys.argv[1]):
+if len(sys.argv) < 2 or not os.path.exists(sys.argv[1]):
     # Parse options if called interactively
-    script = sys.argv[1]
-
     def usage():
         print "Usage: %s [OPTION]..." % sys.argv[0]
         print "Options:"
@@ -79,16 +78,16 @@ if not os.path.exists(sys.argv[1]):
             password = optval
         elif opt == "-r" or opt == "--role":
             role = optval
+        elif opt == "-x" or opt == "--xmlrpc":
+            xmlrpc = True
         elif opt == "--help":
             usage()
-else:
-    # Do not parse options if called by a script
-    opts = None
 
 try:
     # If any XML-RPC options have been specified, do not try
     # connecting directly to the DB.
-    if opts:
+    if (url, method, user, password, role, xmlrpc) != \
+       (None, None, None, None, None, False):
         raise Exception
         
     # Otherwise, first try connecting directly to the DB. If this
@@ -147,6 +146,40 @@ else:
     if role is not None:
         auth['Role'] = role
 
+# More convenient multicall support
+multi = False
+calls = []
+
+def begin():
+    global multi, calls
+
+    if calls:
+        raise Exception, "multicall already in progress"
+
+    multi = True
+
+def commit():
+    global multi, calls
+
+    if calls:
+        ret = []
+        multi = False
+        results = system.multicall(calls)
+        for result in results:
+            if type(result) == type({}):
+                raise xmlrpclib.Fault(item['faultCode'], item['faultString'])
+            elif type(result) == type([]):
+                ret.append(result[0])
+            else:
+                raise ValueError, "unexpected type in multicall result"
+    else:
+        ret = None
+
+    calls = []
+    multi = False
+
+    return ret
+
 class Callable:
     """
     Wrapper to call a method either directly or remotely. Initialize
@@ -186,11 +219,17 @@ class Callable:
         requires it and it has not been specified.
         """
 
+        global multi, calls
+
         if self.auth and \
            (not args or not isinstance(args[0], dict) or \
             (not args[0].has_key('AuthMethod') and \
              not args[0].has_key('session'))):
-            return self.func(auth, *args, **kwds)
+            args = (auth,) + args
+
+        if multi:
+            calls.append({'methodName': self.name, 'params': list(args)})
+            return None
         else:
             return self.func(*args, **kwds)
 
@@ -231,7 +270,7 @@ def help(thing):
     pyhelp(thing)
 
 # If called by a script
-if os.path.exists(sys.argv[1]):
+if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
     # Pop us off the argument stack
     sys.argv.pop(0)
     execfile(sys.argv[0])