1 """a clumsy attempt at a macro language to let the programmer execute code on the server (ex: determine 64bit)""" 2 3 from . import is64bit 4 5 6 def macro_call(macro_name, args, kwargs): 7 """allow the programmer to perform limited processing on the server by passing macro names and args 8 9 :new_key - the key name the macro will create 10 :args[0] - macro name 11 :args[1:] - any arguments 12 :code - the value of the keyword item 13 :kwargs - the connection keyword dictionary. ??key has been removed 14 --> the value to put in for kwargs['name'] = value 15 """ 16 if isinstance(args, (str, str)): 17 args = [ 18 args 19 ] # the user forgot to pass a sequence, so make a string into args[0] 20 new_key = args[0] 21 try: 22 if macro_name == "is64bit": 23 if is64bit.Python(): # if on 64 bit Python 24 return new_key, args[1] # return first argument 25 else: 26 try: 27 return new_key, args[2] # else return second argument (if defined) 28 except IndexError: 29 return new_key, "" # else return blank 30 31 elif ( 32 macro_name == "getuser" 33 ): # get the name of the user the server is logged in under 34 if not new_key in kwargs: 35 import getpass 36 37 return new_key, getpass.getuser() 38 39 elif macro_name == "getnode": # get the name of the computer running the server 40 import platform 41 42 try: 43 return new_key, args[1] % platform.node() 44 except IndexError: 45 return new_key, platform.node() 46 47 elif macro_name == "getenv": # expand the server's environment variable args[1] 48 import os 49 50 try: 51 dflt = args[2] # if not found, default from args[2] 52 except IndexError: # or blank 53 dflt = "" 54 return new_key, os.environ.get(args[1], dflt) 55 56 elif macro_name == "auto_security": 57 if ( 58 not "user" in kwargs or not kwargs["user"] 59 ): # missing, blank, or Null username 60 return new_key, "Integrated Security=SSPI" 61 return new_key, "User ID=%(user)s; Password=%(password)s" % kwargs 62 63 elif ( 64 macro_name == "find_temp_test_path" 65 ): # helper function for testing ado operation -- undocumented 66 import os 67 import tempfile 68 69 return new_key, os.path.join( 70 tempfile.gettempdir(), "adodbapi_test", args[1] 71 ) 72 73 raise ValueError(f"Unknown connect string macro={macro_name}") 74 except: 75 raise ValueError(f"Error in macro processing {macro_name} {args!r}") 76 77 78 def process( 79 args, kwargs, expand_macros=False 80 ): # --> connection string with keyword arguments processed. 81 """attempts to inject arguments into a connection string using Python "%" operator for strings 82 83 co: adodbapi connection object 84 args: positional parameters from the .connect() call 85 kvargs: keyword arguments from the .connect() call 86 """ 87 try: 88 dsn = args[0] 89 except IndexError: 90 dsn = None 91 # as a convenience the first argument may be django settings 92 if isinstance(dsn, dict): 93 kwargs.update(dsn) 94 # the connection string is passed to the connection as part of the keyword dictionary 95 elif dsn: 96 kwargs["connection_string"] = dsn 97 try: 98 a1 = args[1] 99 except IndexError: 100 a1 = None 101 # historically, the second positional argument might be a timeout value 102 if isinstance(a1, int): 103 kwargs["timeout"] = a1 104 # if the second positional argument is a string, then it is user 105 elif isinstance(a1, str): 106 kwargs["user"] = a1 107 # if the second positional argument is a dictionary, use it as keyword arguments, too 108 elif isinstance(a1, dict): 109 kwargs.update(a1) 110 try: 111 kwargs["password"] = args[2] # the third positional argument is password 112 kwargs["host"] = args[3] # the fourth positional argument is host name 113 kwargs["database"] = args[4] # the fifth positional argument is database name 114 except IndexError: 115 pass 116 117 # make sure connection string is defined somehow 118 if not "connection_string" in kwargs: 119 try: # perhaps 'dsn' was defined 120 kwargs["connection_string"] = kwargs["dsn"] 121 except KeyError: 122 try: # as a last effort, use the "host" keyword 123 kwargs["connection_string"] = kwargs["host"] 124 except KeyError: 125 raise TypeError("Must define 'connection_string' for ado connections") 126 if expand_macros: 127 for kwarg in list(kwargs.keys()): 128 if kwarg.startswith("macro_"): # If a key defines a macro 129 macro_name = kwarg[6:] # name without the "macro_" 130 macro_code = kwargs.pop( 131 kwarg 132 ) # we remove the macro_key and get the code to execute 133 new_key, rslt = macro_call( 134 macro_name, macro_code, kwargs 135 ) # run the code in the local context 136 kwargs[new_key] = rslt # put the result back in the keywords dict 137 return kwargs 138