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 __author__ = "Mathieu Fenniak"
31
32 import datetime
33 import decimal
34 import struct
35 from errors import NotSupportedError
36
39
41 - def __init__(self, microseconds, days, months):
42 self.microseconds = microseconds
43 self.days = days
44 self.months = months
45
47 return "<Interval %s months %s days %s microseconds>" % (self.months, self.days, self.microseconds)
48
50 c = cmp(self.months, other.months)
51 if c != 0: return c
52 c = cmp(self.days, other.days)
53 if c != 0: return c
54 return cmp(self.microseconds, other.microseconds)
55
57 data = py_types.get(typ)
58 if data == None:
59 raise NotSupportedError("type %r not mapped to pg type" % typ)
60 type_oid = data.get("tid")
61 if type_oid == None:
62 raise InternalError("type %r has no type_oid" % typ)
63 elif type_oid == -1:
64
65 return type_oid, 0
66
67 if data.get("bin_out"):
68 format = 1
69 elif data.get("txt_out"):
70 format = 0
71 else:
72 raise InternalError("no conversion fuction for type %r" % typ)
73 return type_oid, format
74
76 typ = type(v)
77 data = py_types.get(typ)
78 if data == None:
79 raise NotSupportedError("type %r not mapped to pg type" % typ)
80 elif data.get("tid") == -1:
81
82 return None
83 if fc == 0:
84 func = data.get("txt_out")
85 elif fc == 1:
86 func = data.get("bin_out")
87 else:
88 raise InternalError("unrecognized format code %r" % fc)
89 if func == None:
90 raise NotSupportedError("type %r, format code %r not supported" % (typ, fc))
91 return func(v, **kwargs)
92
94 type_oid = description['type_oid']
95 data = pg_types.get(type_oid)
96 if data == None:
97 raise NotSupportedError("type oid %r not mapped to py type" % type_oid)
98
99 if data.get("bin_in"):
100 format = 1
101 elif data.get("txt_in"):
102 format = 0
103 else:
104 raise InternalError("no conversion fuction for type oid %r" % type_oid)
105 return format
106
108 if v == None:
109
110 return None
111 type_oid = description['type_oid']
112 format = description['format']
113 data = pg_types.get(type_oid)
114 if data == None:
115 raise NotSupportedError("type oid %r not supported" % type_oid)
116 if format == 0:
117 func = data.get("txt_in")
118 elif format == 1:
119 func = data.get("bin_in")
120 else:
121 raise NotSupportedError("format code %r not supported" % format)
122 if func == None:
123 raise NotSupportedError("data response format %r, type %r not supported" % (format, type_oid))
124 return func(v, **kwargs)
125
127 return data == "\x01"
128
130 if v:
131 return 't'
132 else:
133 return 'f'
134
136 return struct.unpack("!h", data)[0]
137
139 return struct.unpack("!i", data)[0]
140
142 return struct.pack("!i", v)
143
145 return struct.unpack("!q", data)[0]
146
148 return struct.unpack("!f", data)[0]
149
151 return struct.unpack("!d", data)[0]
152
154 return struct.pack("!d", v)
155
157 if integer_datetimes:
158
159 val = struct.unpack("!q", data)[0]
160 return datetime.datetime(2000, 1, 1) + datetime.timedelta(microseconds = val)
161 else:
162
163 val = struct.unpack("!d", data)[0]
164 return datetime.datetime(2000, 1, 1) + datetime.timedelta(seconds = val)
165
167 delta = v - datetime.datetime(2000, 1, 1)
168 val = delta.microseconds + (delta.seconds * 1000000) + (delta.days * 86400000000)
169 if integer_datetimes:
170 return struct.pack("!q", val)
171 else:
172 return struct.pack("!d", val / 1000.0 / 1000.0)
173
175 year = int(data[0:4])
176 month = int(data[5:7])
177 day = int(data[8:10])
178 return datetime.date(year, month, day)
179
182
184 hour = int(data[0:2])
185 minute = int(data[3:5])
186 sec = decimal.Decimal(data[6:])
187 return datetime.time(hour, minute, int(sec), int((sec - int(sec)) * 1000000))
188
191
193 if data.find(".") == -1:
194 return int(data)
195 else:
196 return decimal.Decimal(data)
197
200
201
202
203
204
205
206
207
208 pg_to_py_encodings = {
209
210 "mule_internal": None,
211 "euc_tw": None,
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226 "euc_cn": "gb2312",
227 "iso_8859_5": "is8859_5",
228 "iso_8859_6": "is8859_6",
229 "iso_8859_7": "is8859_7",
230 "iso_8859_8": "is8859_8",
231 "koi8": "koi8_r",
232 "latin1": "iso8859-1",
233 "latin2": "iso8859_2",
234 "latin3": "iso8859_3",
235 "latin4": "iso8859_4",
236 "latin5": "iso8859_9",
237 "latin6": "iso8859_10",
238 "latin7": "iso8859_13",
239 "latin8": "iso8859_14",
240 "latin9": "iso8859_15",
241 "sql_ascii": "ascii",
242 "win866": "cp886",
243 "win874": "cp874",
244 "win1250": "cp1250",
245 "win1251": "cp1251",
246 "win1252": "cp1252",
247 "win1253": "cp1253",
248 "win1254": "cp1254",
249 "win1255": "cp1255",
250 "win1256": "cp1256",
251 "win1257": "cp1257",
252 "win1258": "cp1258",
253 }
254
257
258 -def varcharin(data, client_encoding, **kwargs):
260
261 -def textout(v, client_encoding, **kwargs):
262 return v.encode(encoding_convert(client_encoding))
263
265 year = int(data[0:4])
266 month = int(data[5:7])
267 day = int(data[8:10])
268 hour = int(data[11:13])
269 minute = int(data[14:16])
270 tz_sep = data.rfind("-")
271 sec = decimal.Decimal(data[17:tz_sep])
272 tz = data[tz_sep:]
273 return datetime.datetime(year, month, day, hour, minute, int(sec), int((sec - int(sec)) * 1000000), FixedOffsetTz(tz))
274
277 self.hrs = int(hrs)
278 self.name = hrs
279
281 return datetime.timedelta(hours=1) * self.hrs
282
285
287 return datetime.timedelta(0)
288
290 if not isinstance(other, FixedOffsetTz):
291 return False
292 return self.hrs == other.hrs
293
296
299
300
302 if integer_datetimes:
303 microseconds, days, months = struct.unpack("!qii", data)
304 else:
305 seconds, days, months = struct.unpack("!dii", data)
306 microseconds = int(seconds * 1000 * 1000)
307 return Interval(microseconds, days, months)
308
310 if integer_datetimes:
311 return struct.pack("!qii", data.microseconds, data.days, data.months)
312 else:
313 return struct.pack("!dii", data.microseconds / 1000.0 / 1000.0, data.days, data.months)
314
315 py_types = {
316 bool: {"tid": 16, "txt_out": boolout},
317 int: {"tid": 23, "bin_out": int4send},
318 long: {"tid": 1700, "txt_out": numeric_out},
319 str: {"tid": 25, "txt_out": textout},
320 unicode: {"tid": 25, "txt_out": textout},
321 float: {"tid": 701, "bin_out": float8send},
322 decimal.Decimal: {"tid": 1700, "txt_out": numeric_out},
323 Bytea: {"tid": 17, "bin_out": byteasend},
324 datetime.datetime: {"tid": 1114, "bin_out": timestamp_send},
325 datetime.date: {"tid": 1082, "txt_out": date_out},
326 datetime.time: {"tid": 1083, "txt_out": time_out},
327 Interval: {"tid": 1186, "bin_out": interval_send},
328 type(None): {"tid": -1},
329 }
330
331 pg_types = {
332 16: {"bin_in": boolrecv},
333 17: {"bin_in": bytearecv},
334 19: {"txt_in": varcharin},
335 20: {"bin_in": int8recv},
336 21: {"bin_in": int2recv},
337 23: {"bin_in": int4recv},
338 25: {"txt_in": varcharin},
339 26: {"txt_in": numeric_in},
340 700: {"bin_in": float4recv},
341 701: {"bin_in": float8recv},
342 1042: {"txt_in": varcharin},
343 1043: {"txt_in": varcharin},
344 1082: {"txt_in": date_in},
345 1083: {"txt_in": time_in},
346 1114: {"bin_in": timestamp_recv},
347 1184: {"txt_in": timestamptz_in},
348 1186: {"bin_in": interval_recv},
349 1700: {"txt_in": numeric_in},
350 2275: {"txt_in": varcharin},
351 }
352