File size: 5,766 Bytes
375a1cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
""" a clumsy attempt at a macro language to let the programmer execute code on the server (ex: determine 64bit)"""
from . import is64bit as is64bit


def macro_call(macro_name, args, kwargs):
    """allow the programmer to perform limited processing on the server by passing macro names and args



    :new_key - the key name the macro will create

    :args[0] - macro name

    :args[1:] - any arguments

    :code - the value of the keyword item

    :kwargs - the connection keyword dictionary. ??key has been removed

    --> the value to put in for kwargs['name'] = value

    """
    if isinstance(args, (str, str)):
        args = [
            args
        ]  # the user forgot to pass a sequence, so make a string into args[0]
    new_key = args[0]
    try:
        if macro_name == "is64bit":
            if is64bit.Python():  # if on 64 bit Python
                return new_key, args[1]  # return first argument
            else:
                try:
                    return new_key, args[2]  # else return second argument (if defined)
                except IndexError:
                    return new_key, ""  # else return blank

        elif (
            macro_name == "getuser"
        ):  # get the name of the user the server is logged in under
            if not new_key in kwargs:
                import getpass

                return new_key, getpass.getuser()

        elif macro_name == "getnode":  # get the name of the computer running the server
            import platform

            try:
                return new_key, args[1] % platform.node()
            except IndexError:
                return new_key, platform.node()

        elif macro_name == "getenv":  # expand the server's environment variable args[1]
            try:
                dflt = args[2]  # if not found, default from args[2]
            except IndexError:  # or blank
                dflt = ""
            return new_key, os.environ.get(args[1], dflt)

        elif macro_name == "auto_security":
            if (
                not "user" in kwargs or not kwargs["user"]
            ):  # missing, blank, or Null username
                return new_key, "Integrated Security=SSPI"
            return new_key, "User ID=%(user)s; Password=%(password)s" % kwargs

        elif (
            macro_name == "find_temp_test_path"
        ):  # helper function for testing ado operation -- undocumented
            import os
            import tempfile

            return new_key, os.path.join(
                tempfile.gettempdir(), "adodbapi_test", args[1]
            )

        raise ValueError("Unknown connect string macro=%s" % macro_name)
    except:
        raise ValueError("Error in macro processing %s %s" % (macro_name, repr(args)))


def process(

    args, kwargs, expand_macros=False

):  # --> connection string with keyword arguments processed.
    """attempts to inject arguments into a connection string using Python "%" operator for strings



    co: adodbapi connection object

    args: positional parameters from the .connect() call

    kvargs: keyword arguments from the .connect() call

    """
    try:
        dsn = args[0]
    except IndexError:
        dsn = None
    if isinstance(
        dsn, dict
    ):  # as a convenience the first argument may be django settings
        kwargs.update(dsn)
    elif (
        dsn
    ):  # the connection string is passed to the connection as part of the keyword dictionary
        kwargs["connection_string"] = dsn
    try:
        a1 = args[1]
    except IndexError:
        a1 = None
    # historically, the second positional argument might be a timeout value
    if isinstance(a1, int):
        kwargs["timeout"] = a1
    # if the second positional argument is a string, then it is user
    elif isinstance(a1, str):
        kwargs["user"] = a1
    # if the second positional argument is a dictionary, use it as keyword arguments, too
    elif isinstance(a1, dict):
        kwargs.update(a1)
    try:
        kwargs["password"] = args[2]  # the third positional argument is password
        kwargs["host"] = args[3]  # the fourth positional argument is host name
        kwargs["database"] = args[4]  # the fifth positional argument is database name
    except IndexError:
        pass

    # make sure connection string is defined somehow
    if not "connection_string" in kwargs:
        try:  # perhaps 'dsn' was defined
            kwargs["connection_string"] = kwargs["dsn"]
        except KeyError:
            try:  # as a last effort, use the "host" keyword
                kwargs["connection_string"] = kwargs["host"]
            except KeyError:
                raise TypeError("Must define 'connection_string' for ado connections")
    if expand_macros:
        for kwarg in list(kwargs.keys()):
            if kwarg.startswith("macro_"):  # If a key defines a macro
                macro_name = kwarg[6:]  # name without the "macro_"
                macro_code = kwargs.pop(
                    kwarg
                )  # we remove the macro_key and get the code to execute
                new_key, rslt = macro_call(
                    macro_name, macro_code, kwargs
                )  # run the code in the local context
                kwargs[new_key] = rslt  # put the result back in the keywords dict
    # special processing for PyRO IPv6 host address
    try:
        s = kwargs["proxy_host"]
        if ":" in s:  # it is an IPv6 address
            if s[0] != "[":  # is not surrounded by brackets
                kwargs["proxy_host"] = s.join(("[", "]"))  # put it in brackets
    except KeyError:
        pass
    return kwargs