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 """Input Conversion converts Python data types to be made appropriate for MySQL
30 parameters.
31
32 The main function of these conversions for simple data types is to escape them
33 (such as escaping quotes in strings). It also handles converting more
34 elaborate data structures, such as `datetime` objects, to strings that MySQL
35 can parse.
36
37 The base class `Input_Conversion` defines the API for converting values.
38
39 The class `Basic_Conversion` is the default conversion used if you do not specify
40 a conversion instance.
41 """
42
43 __version__ = '$Revision: 1.5 $'
44
45 import datetime
46 import decimal
47 import sets
48 import types
49
50 import mysql.util.string
51
74
75
77
78 """The default conversion class used if none is specified.
79
80 It can handle the following Python types:
81
82 - ``int``: Returned as-is.
83 - ``long``: Returned as-is.
84 - ``float``: Returned as-is.
85 - ``None``: Converts to "NULL".
86 - ``str``: Escaped string.
87 - ``bool``: Converted to 1 or 0.
88 - ``decimal.Decimal``: Returned as a string.
89 - ``dict``: Comma seperated list of escaped values. (Useful for sets.)
90 - ``list``: Comma seperated list of escaped values.
91 - ``tuple``: Comma seperated list of escaped values.
92 - ``sets.Set``: Comma seperated list of escaped values.
93 - ``datetime.datetime``: ``%Y-%m-%d %H:%M:%S``
94 - ``datetime.time``: ``%H:%M:%S``
95 - ``datetime.timedelta``: ``%H:%M:%S`` possibly negative.
96 - ``datetime.date``: ``%Y-%m-%d``
97
98 For MySQL "BIT" fields, you may use integers, or binary strings (such as
99 '\x10\x04' which has bits 13 and 3 set).
100
101 If the type is not known, the default behavior is to first call ``str`` on
102 the object, and then escape it.
103 """
104
106 self._type_map = {int: self._number,
107 long: self._number,
108 float: self._number,
109 types.NoneType: self._none,
110 str: mysql.util.string.escape,
111 decimal.Decimal: str,
112 dict: self._dict,
113 list: self._sequence,
114 tuple: self._sequence,
115 sets.Set: self._sequence,
116 datetime.datetime: self._datetime,
117 datetime.time: self._time,
118 datetime.timedelta: self._timedelta,
119 datetime.date: self._date,
120 bool: self._bool,
121 }
122
124 return tuple([ self._type_map.get(type(value), self._escape)(value) for value in values ])
125
127 return value
128
130 return int(value)
131
133 return 'NULL'
134
137
140
145
147 return value.strftime('\'%Y-%m-%d %H:%M:%S\'')
148
150 return value.strftime('\'%H:%M:%S\'')
151
153
154 if value.days < 0:
155 value = -value
156 neg = '-'
157 else:
158 neg = ''
159
160 hours = value.days*24 + value.seconds/3600
161
162 if hours > 838:
163 raise OverflowError('Time value is too large.')
164 minutes = (value.seconds % 3600) / 60
165 seconds = value.seconds % 60
166
167 return '\'%s%i:%i:%i\'' % (neg, hours, minutes, seconds)
168
170 return value.strftime('\'%Y-%m-%d\'')
171