| 58 | format = Format.BINARY |
| 59 | |
| 60 | def dump(self, obj): |
| 61 | import struct |
| 62 | # binary array format: |
| 63 | # - 4 bytes: number of dimensions (1 for 1D array) |
| 64 | # - 4 bytes: has null flag (1 if any element is null) |
| 65 | # - 4 bytes: element type OID (1043 for varchar) |
| 66 | # - 4 bytes: dimension size |
| 67 | # - 4 bytes: lower bound (1) |
| 68 | # For each element: |
| 69 | # - 4 bytes: element length (-1 for null, otherwise byte length) |
| 70 | # - N bytes: element data (if not null) |
| 71 | |
| 72 | has_null = 1 if any(e is None for e in obj) else 0 |
| 73 | elem_oid = 1043 # varchar OID |
| 74 | header = struct.pack('>iiiii', 1, has_null, elem_oid, len(obj), 1) |
| 75 | |
| 76 | elements = [] |
| 77 | for e in obj: |
| 78 | if e is None: |
| 79 | elements.append(struct.pack('>i', -1)) |
| 80 | else: |
| 81 | data = str(e).encode('utf-8') |
| 82 | elements.append(struct.pack('>i', len(data)) + data) |
| 83 | |
| 84 | return header + b''.join(elements) |
| 85 | |
| 86 | def register_varchar_array_type(connection, binary): |
| 87 | """Register varchar[] type dumper with the connection based on mode.""" |