sqlalchemy-iris 0.5.0b3__py3-none-any.whl → 0.6.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- intersystems_iris/_BufferReader.py +10 -0
- intersystems_iris/_BufferWriter.py +32 -0
- intersystems_iris/_ConnectionInformation.py +54 -0
- intersystems_iris/_ConnectionParameters.py +18 -0
- intersystems_iris/_Constant.py +38 -0
- intersystems_iris/_DBList.py +499 -0
- intersystems_iris/_Device.py +69 -0
- intersystems_iris/_GatewayContext.py +25 -0
- intersystems_iris/_GatewayException.py +4 -0
- intersystems_iris/_GatewayUtility.py +74 -0
- intersystems_iris/_IRIS.py +1294 -0
- intersystems_iris/_IRISConnection.py +516 -0
- intersystems_iris/_IRISEmbedded.py +85 -0
- intersystems_iris/_IRISGlobalNode.py +273 -0
- intersystems_iris/_IRISGlobalNodeView.py +25 -0
- intersystems_iris/_IRISIterator.py +143 -0
- intersystems_iris/_IRISList.py +360 -0
- intersystems_iris/_IRISNative.py +208 -0
- intersystems_iris/_IRISOREF.py +4 -0
- intersystems_iris/_IRISObject.py +424 -0
- intersystems_iris/_IRISReference.py +133 -0
- intersystems_iris/_InStream.py +149 -0
- intersystems_iris/_LegacyIterator.py +135 -0
- intersystems_iris/_ListItem.py +15 -0
- intersystems_iris/_ListReader.py +84 -0
- intersystems_iris/_ListWriter.py +157 -0
- intersystems_iris/_LogFileStream.py +115 -0
- intersystems_iris/_MessageHeader.py +51 -0
- intersystems_iris/_OutStream.py +25 -0
- intersystems_iris/_PrintStream.py +65 -0
- intersystems_iris/_PythonGateway.py +850 -0
- intersystems_iris/_SharedMemorySocket.py +87 -0
- intersystems_iris/__init__.py +79 -0
- intersystems_iris/__main__.py +7 -0
- intersystems_iris/dbapi/_Column.py +56 -0
- intersystems_iris/dbapi/_DBAPI.py +2295 -0
- intersystems_iris/dbapi/_Descriptor.py +46 -0
- intersystems_iris/dbapi/_IRISStream.py +63 -0
- intersystems_iris/dbapi/_Message.py +158 -0
- intersystems_iris/dbapi/_Parameter.py +138 -0
- intersystems_iris/dbapi/_ParameterCollection.py +133 -0
- intersystems_iris/dbapi/_ResultSetRow.py +314 -0
- intersystems_iris/dbapi/_SQLType.py +32 -0
- intersystems_iris/dbapi/__init__.py +0 -0
- intersystems_iris/dbapi/preparser/_PreParser.py +1658 -0
- intersystems_iris/dbapi/preparser/_Scanner.py +391 -0
- intersystems_iris/dbapi/preparser/_Token.py +81 -0
- intersystems_iris/dbapi/preparser/_TokenList.py +251 -0
- intersystems_iris/dbapi/preparser/__init__.py +0 -0
- intersystems_iris/pex/_BusinessHost.py +101 -0
- intersystems_iris/pex/_BusinessOperation.py +105 -0
- intersystems_iris/pex/_BusinessProcess.py +214 -0
- intersystems_iris/pex/_BusinessService.py +95 -0
- intersystems_iris/pex/_Common.py +228 -0
- intersystems_iris/pex/_Director.py +24 -0
- intersystems_iris/pex/_IRISBusinessOperation.py +5 -0
- intersystems_iris/pex/_IRISBusinessService.py +18 -0
- intersystems_iris/pex/_IRISInboundAdapter.py +5 -0
- intersystems_iris/pex/_IRISOutboundAdapter.py +17 -0
- intersystems_iris/pex/_InboundAdapter.py +57 -0
- intersystems_iris/pex/_Message.py +6 -0
- intersystems_iris/pex/_OutboundAdapter.py +46 -0
- intersystems_iris/pex/__init__.py +25 -0
- iris/__init__.py +25 -0
- iris/iris_site.py +13 -0
- iris/irisbuiltins.py +97 -0
- iris/irisloader.py +199 -0
- irisnative/_IRISNative.py +9 -0
- irisnative/__init__.py +10 -0
- {sqlalchemy_iris-0.5.0b3.dist-info → sqlalchemy_iris-0.6.0b1.dist-info}/METADATA +1 -1
- sqlalchemy_iris-0.6.0b1.dist-info/RECORD +83 -0
- sqlalchemy_iris-0.6.0b1.dist-info/top_level.txt +4 -0
- sqlalchemy_iris-0.5.0b3.dist-info/RECORD +0 -14
- sqlalchemy_iris-0.5.0b3.dist-info/top_level.txt +0 -1
- {sqlalchemy_iris-0.5.0b3.dist-info → sqlalchemy_iris-0.6.0b1.dist-info}/LICENSE +0 -0
- {sqlalchemy_iris-0.5.0b3.dist-info → sqlalchemy_iris-0.6.0b1.dist-info}/WHEEL +0 -0
- {sqlalchemy_iris-0.5.0b3.dist-info → sqlalchemy_iris-0.6.0b1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
import intersystems_iris._ListReader
|
2
|
+
|
3
|
+
class _BufferReader(intersystems_iris._ListReader._ListReader):
|
4
|
+
|
5
|
+
def __init__(self, header, buffer, locale):
|
6
|
+
self.header = header
|
7
|
+
super().__init__(buffer, locale)
|
8
|
+
|
9
|
+
def _get_header_count(self):
|
10
|
+
return self.header._get_count()
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import intersystems_iris._ListWriter
|
2
|
+
import intersystems_iris._MessageHeader
|
3
|
+
|
4
|
+
class _BufferWriter(intersystems_iris._ListWriter._ListWriter):
|
5
|
+
|
6
|
+
def __init__(self, locale, is_unicode, compact_double):
|
7
|
+
super().__init__(locale, is_unicode, compact_double)
|
8
|
+
self.offset = intersystems_iris._MessageHeader._MessageHeader.HEADER_SIZE
|
9
|
+
|
10
|
+
def _write_header(self, function_code):
|
11
|
+
self.buffer[12] = function_code[0]
|
12
|
+
self.buffer[13] = function_code[1]
|
13
|
+
self.offset = intersystems_iris._MessageHeader._MessageHeader.HEADER_SIZE
|
14
|
+
|
15
|
+
def _write_header_sysio(self, sysio_code):
|
16
|
+
code_int = sysio_code + 49728
|
17
|
+
code_bytes = code_int.to_bytes(2, 'little')
|
18
|
+
self.buffer[12] = code_bytes[0]
|
19
|
+
self.buffer[13] = code_bytes[1]
|
20
|
+
self.offset = intersystems_iris._MessageHeader._MessageHeader.HEADER_SIZE
|
21
|
+
|
22
|
+
def _set_connection_info(self, connection_info):
|
23
|
+
self._locale = connection_info._locale
|
24
|
+
self._is_unicode = connection_info._is_unicode
|
25
|
+
self._compact_double = connection_info._compact_double
|
26
|
+
|
27
|
+
def _get_header_buffer(self):
|
28
|
+
return self.buffer[0:intersystems_iris._MessageHeader._MessageHeader.HEADER_SIZE]
|
29
|
+
|
30
|
+
def _get_data_buffer(self):
|
31
|
+
return self.buffer[intersystems_iris._MessageHeader._MessageHeader.HEADER_SIZE:self.offset]
|
32
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import intersystems_iris._Constant
|
2
|
+
|
3
|
+
class _ConnectionInformation(object):
|
4
|
+
|
5
|
+
def __init__(self):
|
6
|
+
self.protocol_version = intersystems_iris._Constant._Constant.PROTOCOL_VERSION
|
7
|
+
self._is_unicode = True
|
8
|
+
self._compact_double = False
|
9
|
+
self._locale = "latin-1"
|
10
|
+
self._delimited_ids = 0
|
11
|
+
self._server_version = ""
|
12
|
+
self._server_version_major = 0
|
13
|
+
self._server_version_minor = 0
|
14
|
+
self._iris_install_dir = ""
|
15
|
+
self._server_job_number = -1
|
16
|
+
|
17
|
+
def _set_server_locale(self, locale):
|
18
|
+
self._locale = self._map_server_locale(locale)
|
19
|
+
|
20
|
+
def _parse_server_version(self, server_version):
|
21
|
+
split_1 = server_version.split("|")
|
22
|
+
self._server_version = split_1[0]
|
23
|
+
if len(split_1)>1: self._iris_install_dir = split_1[1]
|
24
|
+
if self._server_version.find("Version") > 0:
|
25
|
+
version = server_version[server_version.find("Version")+8:]
|
26
|
+
self._server_version_major = version.split(".")[0]
|
27
|
+
self._server_version_minor = version.split(".")[1]
|
28
|
+
return
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def _map_server_locale(locale):
|
32
|
+
# we need to map IRIS locale literals to Python locale literals
|
33
|
+
_locales = {
|
34
|
+
"LATIN1": "latin_1",
|
35
|
+
"LATIN2": "iso8859_2",
|
36
|
+
"LATINC": "iso8859_5",
|
37
|
+
"LATINA": "iso8859_6",
|
38
|
+
"LATING": "iso8859_7",
|
39
|
+
"LATINH": "iso8859_8",
|
40
|
+
"LATINT": "iso8859_11",
|
41
|
+
"LATIN9": "iso8859_15",
|
42
|
+
"CP1250": "cp1250",
|
43
|
+
"CP1251": "cp1251",
|
44
|
+
"CP1252": "cp1252",
|
45
|
+
"CP1253": "cp1253",
|
46
|
+
"CP1255": "cp1255",
|
47
|
+
"CP1256": "cp1256",
|
48
|
+
"CP1257": "cp1257",
|
49
|
+
"CP874": "cp874",
|
50
|
+
"UNICODE": "utf-8",
|
51
|
+
}
|
52
|
+
return _locales[locale.upper()] if locale.upper() in _locales else locale
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class _ConnectionParameters(object):
|
2
|
+
"""_ConnectionParameters represents the properties that are implicit to a URL."""
|
3
|
+
def __init__(self):
|
4
|
+
self.hostname = None
|
5
|
+
self.port = None
|
6
|
+
self.namespace = None
|
7
|
+
self.timeout = None
|
8
|
+
self.sharedmemory = False
|
9
|
+
self.logfile = None
|
10
|
+
self.sslcontext = None
|
11
|
+
self.isolationLevel = None
|
12
|
+
self.featureOptions = None
|
13
|
+
|
14
|
+
def _set_sharedmemory(self, sharedmemory):
|
15
|
+
self.sharedmemory = sharedmemory
|
16
|
+
|
17
|
+
def _get_sharedmemory(self):
|
18
|
+
return self.sharedmemory
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class _Constant():
|
2
|
+
|
3
|
+
PROTOCOL_VERSION = 65
|
4
|
+
|
5
|
+
# Message function code
|
6
|
+
MESSAGE_CONNECT = b'Y0'
|
7
|
+
MESSAGE_DISCONNECT = b'Y4'
|
8
|
+
MESSAGE_SHUTDOWN = b'Y6'
|
9
|
+
MESSAGE_PING = b'YQ'
|
10
|
+
MESSAGE_BENCHMARK_ECHO = b'YY'
|
11
|
+
MESSAGE_LOAD_MODULES = b'YP'
|
12
|
+
MESSAGE_DYNAMIC_EXECUTE_CONSTRUCTOR = b'YA'
|
13
|
+
MESSAGE_DYNAMIC_EXECUTE_METHOD = b'YU'
|
14
|
+
MESSAGE_DYNAMIC_EXECUTE_GET = b'YV'
|
15
|
+
MESSAGE_DYNAMIC_EXECUTE_SET = b'YB'
|
16
|
+
MESSAGE_CREATE_OBJECT = b'Y9'
|
17
|
+
MESSAGE_EXCEPTION_RAISED = b'Y5'
|
18
|
+
MESSAGE_GET_LIST = b'YG'
|
19
|
+
MESSAGE_GET_STREAM = b'YH'
|
20
|
+
|
21
|
+
@staticmethod
|
22
|
+
def __convert(code):
|
23
|
+
return code[0]*256+code[1]-22832
|
24
|
+
|
25
|
+
ENUM_MESSAGE_PASSPHRASE = -48
|
26
|
+
ENUM_MESSAGE_CONNECT = __convert.__func__(MESSAGE_CONNECT)
|
27
|
+
ENUM_MESSAGE_DISCONNECT = __convert.__func__(MESSAGE_DISCONNECT)
|
28
|
+
ENUM_MESSAGE_SHUTDOWN = __convert.__func__(MESSAGE_SHUTDOWN)
|
29
|
+
ENUM_MESSAGE_PING = __convert.__func__(MESSAGE_PING)
|
30
|
+
ENUM_MESSAGE_BENCHMARK_ECHO = __convert.__func__(MESSAGE_BENCHMARK_ECHO)
|
31
|
+
ENUM_MESSAGE_LOAD_MODULES = __convert.__func__(MESSAGE_LOAD_MODULES)
|
32
|
+
ENUM_MESSAGE_DYNAMIC_EXECUTE_CONSTRUCTOR = __convert.__func__(MESSAGE_DYNAMIC_EXECUTE_CONSTRUCTOR)
|
33
|
+
ENUM_MESSAGE_DYNAMIC_EXECUTE_METHOD = __convert.__func__(MESSAGE_DYNAMIC_EXECUTE_METHOD)
|
34
|
+
ENUM_MESSAGE_DYNAMIC_EXECUTE_GET = __convert.__func__(MESSAGE_DYNAMIC_EXECUTE_GET)
|
35
|
+
ENUM_MESSAGE_DYNAMIC_EXECUTE_SET = __convert.__func__(MESSAGE_DYNAMIC_EXECUTE_SET)
|
36
|
+
|
37
|
+
# IRISNative messages
|
38
|
+
|
@@ -0,0 +1,499 @@
|
|
1
|
+
import struct
|
2
|
+
import decimal
|
3
|
+
import functools
|
4
|
+
import math
|
5
|
+
import intersystems_iris._IRISOREF
|
6
|
+
import datetime
|
7
|
+
|
8
|
+
class _DBList(object):
|
9
|
+
|
10
|
+
ITEM_UNDEF = -1;
|
11
|
+
ITEM_PLACEHOLDER = 0;
|
12
|
+
ITEM_ASCII = 1;
|
13
|
+
ITEM_UNICODE = 2;
|
14
|
+
ITEM_POSINT = 4;
|
15
|
+
ITEM_NEGINT = 5;
|
16
|
+
ITEM_POSNUM = 6;
|
17
|
+
ITEM_NEGNUM = 7;
|
18
|
+
ITEM_DOUBLE = 8;
|
19
|
+
ITEM_COMPACT_DOUBLE = 9;
|
20
|
+
ITEM_OREF_ASCII = 25;
|
21
|
+
ITEM_OREF_UNICODE = 26;
|
22
|
+
|
23
|
+
@classmethod
|
24
|
+
def _get_list_element(cls, item):
|
25
|
+
buffer = item.buffer
|
26
|
+
offset = item.next_offset
|
27
|
+
item.by_reference = False
|
28
|
+
# if first byte is 0, then length is next 2 bytes
|
29
|
+
if buffer[offset] == 0:
|
30
|
+
length = buffer[offset + 1] | (buffer[offset + 2] << 8);
|
31
|
+
offset += 3
|
32
|
+
# if the length is still 0, then the length is the next 4 bytes
|
33
|
+
if length == 0:
|
34
|
+
length = buffer[offset] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24);
|
35
|
+
offset += 4
|
36
|
+
item.type = buffer[offset]
|
37
|
+
if item.type >= 32 and item.type < 64:
|
38
|
+
item.type = item.type-32
|
39
|
+
item.by_reference = True
|
40
|
+
item.data_offset = offset + 1
|
41
|
+
item.data_length = length - 1
|
42
|
+
item.next_offset = item.data_offset + item.data_length
|
43
|
+
item.is_null = False
|
44
|
+
item.is_undefined = False
|
45
|
+
elif buffer[offset] == 1:
|
46
|
+
item.type = cls.ITEM_UNDEF
|
47
|
+
if item.type >= 32 and item.type < 64:
|
48
|
+
item.type = item.type-32
|
49
|
+
item.by_reference = True
|
50
|
+
item.data_offset = offset + 1
|
51
|
+
item.data_length = 0
|
52
|
+
item.next_offset = item.data_offset
|
53
|
+
item.is_null = True
|
54
|
+
item.is_undefined = True
|
55
|
+
else:
|
56
|
+
item.type = buffer[offset + 1]
|
57
|
+
if item.type >= 32 and item.type < 64:
|
58
|
+
item.type = item.type-32
|
59
|
+
item.by_reference = True
|
60
|
+
item.data_offset = offset + 2
|
61
|
+
item.data_length = buffer[offset] - 2
|
62
|
+
item.next_offset = item.data_offset + item.data_length
|
63
|
+
item.is_null = (item.type == cls.ITEM_PLACEHOLDER) or ((item.type == cls.ITEM_ASCII) and (item.data_length == 0))
|
64
|
+
item.is_undefined = False
|
65
|
+
return
|
66
|
+
|
67
|
+
@classmethod
|
68
|
+
def _get_data_offset(cls, buffer, offset):
|
69
|
+
if buffer[offset] != 0:
|
70
|
+
next_offset = offset + buffer[offset]
|
71
|
+
elif buffer[offset + 1] == 0 and buffer[offset + 2] == 0:
|
72
|
+
if offset + 6 < len(buffer):
|
73
|
+
next_offset = offset + (buffer[offset + 3] | (buffer[offset + 4] << 8) | (buffer[offset + 5] << 16)) + 7
|
74
|
+
elif offset + 2 < len(buffer):
|
75
|
+
next_offset = offset + (buffer[offset + 1] | (buffer[offset + 2] << 8)) + 3
|
76
|
+
return next_offset
|
77
|
+
|
78
|
+
@classmethod
|
79
|
+
def _get(cls, item, locale, asBytes = False, retainAsciiZero = False):
|
80
|
+
if item.is_null:
|
81
|
+
return None
|
82
|
+
func = cls._get_switcher.get(item.type, None)
|
83
|
+
if func is None:
|
84
|
+
raise Exception("Incorrect list format, unknown type: " + item.type)
|
85
|
+
else:
|
86
|
+
return func(item.buffer, item.data_offset, item.data_length, locale, asBytes, retainAsciiZero)
|
87
|
+
|
88
|
+
@classmethod
|
89
|
+
def _grab_ascii_string(cls, buffer, offset, length, locale, asBytes = False, retainAsciiZero = False):
|
90
|
+
byte_array = buffer[offset:offset+length]
|
91
|
+
if not retainAsciiZero and byte_array == b'\x00':
|
92
|
+
return ""
|
93
|
+
if asBytes:
|
94
|
+
return bytes(byte_array)
|
95
|
+
else:
|
96
|
+
try:
|
97
|
+
return byte_array.decode(locale)
|
98
|
+
except:
|
99
|
+
return byte_array.decode('latin-1')
|
100
|
+
|
101
|
+
@classmethod
|
102
|
+
def _grab_unicode_string(cls, buffer, offset, length, *args):
|
103
|
+
return buffer[offset:offset+length].decode("utf-16LE")
|
104
|
+
|
105
|
+
@classmethod
|
106
|
+
def _grab_pos_integer(cls, buffer, offset, length, *args):
|
107
|
+
number = 0
|
108
|
+
for i in range(length):
|
109
|
+
number = number*256 + buffer[offset+length-i-1]
|
110
|
+
return number
|
111
|
+
|
112
|
+
@classmethod
|
113
|
+
def _grab_neg_integer(cls, buffer, offset, length, *args):
|
114
|
+
if length == 0:
|
115
|
+
return -1
|
116
|
+
if length == 1:
|
117
|
+
return (buffer[offset]) - 0x100
|
118
|
+
if length == 2:
|
119
|
+
return (buffer[offset] | buffer[offset+1]<<8) - 0x10000
|
120
|
+
if length == 3:
|
121
|
+
return (buffer[offset] | buffer[offset+1]<<8 | buffer[offset+2]<<16) - 0x1000000
|
122
|
+
if length == 4:
|
123
|
+
return (buffer[offset] | buffer[offset+1]<<8 | buffer[offset+2]<<16 | buffer[offset+3]<<24) - 0x100000000
|
124
|
+
if length == 5:
|
125
|
+
return (buffer[offset] | buffer[offset+1]<<8 | buffer[offset+2]<<16 | buffer[offset+3]<<24 | buffer[offset+4]<<32) - 0x10000000000
|
126
|
+
if length == 6:
|
127
|
+
return (buffer[offset] | buffer[offset+1]<<8 | buffer[offset+2]<<16 | buffer[offset+3]<<24 | buffer[offset+4]<<32 | buffer[offset+5]<<40) - 0x1000000000000
|
128
|
+
if length == 7:
|
129
|
+
return (buffer[offset] | buffer[offset+1]<<8 | buffer[offset+2]<<16 | buffer[offset+3]<<24 | buffer[offset+4]<<32 | buffer[offset+5]<<40 | buffer[offset+6]<<48) - 0x100000000000000
|
130
|
+
if length == 8:
|
131
|
+
return (buffer[offset] | buffer[offset+1]<<8 | buffer[offset+2]<<16 | buffer[offset+3]<<24 | buffer[offset+4]<<32 | buffer[offset+5]<<40 | buffer[offset+6]<<48 | buffer[offset+7]<<56) - 0x10000000000000000
|
132
|
+
raise Exception("Integer out of range")
|
133
|
+
|
134
|
+
@classmethod
|
135
|
+
def _grab_pos_number(cls, buffer, offset, length, *args):
|
136
|
+
num = cls._grab_pos_integer(buffer, offset + 1, length - 1)
|
137
|
+
scale = buffer[offset]
|
138
|
+
if scale > 127:
|
139
|
+
scale -= 256
|
140
|
+
return cls.__parse_decimal(scale, num)
|
141
|
+
|
142
|
+
@classmethod
|
143
|
+
def _grab_neg_number(cls, buffer, offset, length, *args):
|
144
|
+
num = cls._grab_neg_integer(buffer, offset + 1, length - 1)
|
145
|
+
scale = buffer[offset]
|
146
|
+
if scale > 127:
|
147
|
+
scale -= 256
|
148
|
+
return cls.__parse_decimal(scale, num)
|
149
|
+
|
150
|
+
@classmethod
|
151
|
+
def _grab_double(cls, buffer, offset, length, *args):
|
152
|
+
if length != 8: return cls.__grab_compact_float(buffer, offset, length)
|
153
|
+
return struct.unpack('d', buffer[offset:offset+length])[0]
|
154
|
+
|
155
|
+
@classmethod
|
156
|
+
def _grab_compact_double(cls, buffer, offset, length, *args):
|
157
|
+
return struct.unpack('d',b'\x00\x00\x00\x00\x00\x00\x00\x00'[length:]+buffer[offset:offset+length])[0]
|
158
|
+
|
159
|
+
@classmethod
|
160
|
+
def __grab_compact_float(cls, buffer, offset, length):
|
161
|
+
return struct.unpack('f',b'\x00\x00\x00\x00'[length:]+buffer[offset:offset+length])[0]
|
162
|
+
|
163
|
+
@classmethod
|
164
|
+
def _grab_oref_ascii(cls, buffer, offset, length, locale, *args):
|
165
|
+
return intersystems_iris._IRISOREF._IRISOREF(cls._grab_ascii_string(buffer, offset, length, locale, False))
|
166
|
+
|
167
|
+
@classmethod
|
168
|
+
def _grab_oref_unicode(cls, buffer, offset, length, *args):
|
169
|
+
return intersystems_iris._IRISOREF._IRISOREF(cls._grab_unicode_string(buffer, offset, length))
|
170
|
+
|
171
|
+
@classmethod
|
172
|
+
def _set(cls, buffer, offset, data, locale, is_unicode, compact_double):
|
173
|
+
func = cls._set_switcher.get(type(data), None)
|
174
|
+
if func is None:
|
175
|
+
raise Exception("Unsupported argument type: " + str(type(data)))
|
176
|
+
else:
|
177
|
+
return func(buffer, offset, data, locale, is_unicode, compact_double)
|
178
|
+
|
179
|
+
@classmethod
|
180
|
+
def _set_undefined(cls, buffer, offset):
|
181
|
+
buffer[offset] = 1
|
182
|
+
return offset + 1
|
183
|
+
|
184
|
+
@classmethod
|
185
|
+
def _set_null(cls, buffer, offset):
|
186
|
+
return cls._stuff_null(buffer, offset)
|
187
|
+
|
188
|
+
@classmethod
|
189
|
+
def _stuff_null(cls, buffer, offset, data = None, *args):
|
190
|
+
buffer[offset] = 2
|
191
|
+
buffer[offset+1] = cls.ITEM_ASCII
|
192
|
+
return offset+2
|
193
|
+
|
194
|
+
@classmethod
|
195
|
+
def _stuff_bytes(cls, buffer, offset, data, *args):
|
196
|
+
length = len(data)
|
197
|
+
offset = cls.__set_list_length_type(buffer, offset, length, cls.ITEM_ASCII)
|
198
|
+
buffer[offset:offset+length] = data[0:length]
|
199
|
+
offset += length
|
200
|
+
return offset
|
201
|
+
|
202
|
+
@classmethod
|
203
|
+
def _stuff_int(cls, buffer, offset, data, locale, is_unicode, *args):
|
204
|
+
if data > 0x7fffffffffffffff or data < -0x8000000000000000:
|
205
|
+
return cls._stuff_str(buffer, offset, str(data), locale=locale, is_unicode=is_unicode)
|
206
|
+
if data == 0:
|
207
|
+
return cls.__set_list_length_type(buffer, offset, 0, cls.ITEM_POSINT)
|
208
|
+
elif data > 0:
|
209
|
+
length = cls.__get_pos_int_length(data)
|
210
|
+
offset = cls.__set_list_length_type(buffer, offset, length, cls.ITEM_POSINT)
|
211
|
+
offset = cls.__stuff_raw_int(buffer, offset, data, length)
|
212
|
+
return offset
|
213
|
+
else:
|
214
|
+
length = cls.__get_neg_int_length(data)
|
215
|
+
offset = cls.__set_list_length_type(buffer, offset, length, cls.ITEM_NEGINT)
|
216
|
+
offset = cls.__stuff_raw_int(buffer, offset, data, length)
|
217
|
+
return offset
|
218
|
+
|
219
|
+
@classmethod
|
220
|
+
def _stuff_double(cls, buffer, offset, data, locale, is_unicode, compact_double):
|
221
|
+
if compact_double:
|
222
|
+
if data == 0 and math.copysign(1,data) > 0:
|
223
|
+
return cls.__set_list_length_type(buffer, offset, 0, cls.ITEM_DOUBLE)
|
224
|
+
# check if value can be corced to a single-precision value
|
225
|
+
# pack('<f') can throw OverFlowError
|
226
|
+
if struct.unpack('f', struct.pack('f', data))[0] == data:
|
227
|
+
lt = cls.ITEM_DOUBLE
|
228
|
+
data_bytes = struct.pack('<f',data)
|
229
|
+
else:
|
230
|
+
lt = cls.ITEM_COMPACT_DOUBLE
|
231
|
+
data_bytes = struct.pack('<d',data)
|
232
|
+
length = len(data_bytes)
|
233
|
+
#skip zeros
|
234
|
+
for i in range(length):
|
235
|
+
if data_bytes[i] != 0:
|
236
|
+
break
|
237
|
+
offset = cls.__set_list_length_type(buffer, offset, length-i, lt)
|
238
|
+
for j in range(i,length):
|
239
|
+
buffer[offset] = data_bytes[j]
|
240
|
+
offset += 1
|
241
|
+
return offset
|
242
|
+
else: # not compact_double
|
243
|
+
data_bytes = struct.pack('<d', data)
|
244
|
+
length = len(data_bytes)
|
245
|
+
offset = cls.__set_list_length_type(buffer, offset, length, cls.ITEM_DOUBLE)
|
246
|
+
for i in range(length):
|
247
|
+
buffer[offset] = data_bytes[i]
|
248
|
+
offset += 1
|
249
|
+
return offset
|
250
|
+
|
251
|
+
@classmethod
|
252
|
+
def _stuff_decimal(cls, buffer, offset, data, *args):
|
253
|
+
try:
|
254
|
+
if math.isnan(data) or math.isinf(data):
|
255
|
+
return cls._stuff_double(buffer, offset, data, *args)
|
256
|
+
except ValueError as e:
|
257
|
+
if str(data).lower() == "snan":
|
258
|
+
return cls._stuff_double(buffer, offset, decimal.Decimal('nan'), *args)
|
259
|
+
elif str(data).lower() == "-snan":
|
260
|
+
return cls._stuff_double(buffer, offset, decimal.Decimal('-nan'), *args)
|
261
|
+
else:
|
262
|
+
raise e
|
263
|
+
bd = data
|
264
|
+
scale = -bd.as_tuple()[2]
|
265
|
+
unscaled_value = int(bd.scaleb(scale))
|
266
|
+
# Truncate the magnitude if it does not fit into a 63 bit value
|
267
|
+
if cls.__get_bitlength(unscaled_value) > 63:
|
268
|
+
bd_rnd = decimal.Context(prec=19, rounding=decimal.ROUND_HALF_UP).create_decimal(bd)
|
269
|
+
scale = -bd_rnd.as_tuple()[2]
|
270
|
+
unscaled_value = int(bd_rnd.scaleb(scale))
|
271
|
+
if cls.__get_bitlength(unscaled_value) > 63:
|
272
|
+
bd_rnd = decimal.Context(prec=18, rounding=decimal.ROUND_HALF_UP).create_decimal(bd)
|
273
|
+
scale = -bd_rnd.as_tuple()[2]
|
274
|
+
unscaled_value = int(bd_rnd.scaleb(scale))
|
275
|
+
if unscaled_value < 922337203685477581 and unscaled_value > -922337203685477581:
|
276
|
+
unscaled_value = int((decimal.Decimal(unscaled_value)*10).to_integral_exact(rounding=decimal.ROUND_HALF_UP))
|
277
|
+
scale += 1
|
278
|
+
if cls.__get_bitlength(unscaled_value) > 63:
|
279
|
+
raise Exception("Decimal out of range")
|
280
|
+
# Round the extend scale values in the 128-145 range
|
281
|
+
if scale < -127 or scale > 128:
|
282
|
+
if scale > 128:
|
283
|
+
prec_adj = -scale + 128
|
284
|
+
else:
|
285
|
+
prec_adj = -scale - 127
|
286
|
+
unscaled_value = int(decimal.Decimal(unscaled_value).scaleb(prec_adj).to_integral(rounding=decimal.ROUND_HALF_UP))
|
287
|
+
scale += prec_adj
|
288
|
+
if unscaled_value == 0:
|
289
|
+
scale = 0
|
290
|
+
if cls.__get_bitlength(unscaled_value) > 63:
|
291
|
+
raise Exception("Decimal out of range")
|
292
|
+
# If can store in type 6, 7
|
293
|
+
if scale < 129 and scale > -128:
|
294
|
+
if unscaled_value >= 0:
|
295
|
+
length = cls.__get_pos_int_length(unscaled_value)
|
296
|
+
offset = cls.__set_list_length_type(buffer, offset, length + 1, cls.ITEM_POSNUM)
|
297
|
+
else:
|
298
|
+
length = cls.__get_neg_int_length(unscaled_value)
|
299
|
+
offset = cls.__set_list_length_type(buffer, offset, length + 1, cls.ITEM_NEGNUM)
|
300
|
+
scale = -scale
|
301
|
+
if scale < 0:
|
302
|
+
scale += 256
|
303
|
+
buffer[offset] = scale
|
304
|
+
offset += 1
|
305
|
+
offset = cls.__stuff_raw_int(buffer, offset, unscaled_value, length)
|
306
|
+
return offset
|
307
|
+
# Out of range for IRIS Numeric SQLType
|
308
|
+
return cls._stuff_double(buffer, offset, data, *args)
|
309
|
+
|
310
|
+
@classmethod
|
311
|
+
def _stuff_str(cls, buffer, offset, data, locale, is_unicode, *args):
|
312
|
+
if type(data)==str and len(data) == 0:
|
313
|
+
return cls.__stuff_empty_string(buffer, offset)
|
314
|
+
is_oref = False
|
315
|
+
if type(data) == intersystems_iris._IRISOREF._IRISOREF:
|
316
|
+
data = data._oref
|
317
|
+
is_oref = True
|
318
|
+
offset_saved = offset
|
319
|
+
offset = cls.__stuff_8bit_ascii(buffer, offset, data, is_oref)
|
320
|
+
if offset == -1:
|
321
|
+
offset = offset_saved
|
322
|
+
if is_unicode:
|
323
|
+
offset = cls.__stuff_unicode(buffer, offset, data, is_oref)
|
324
|
+
else:
|
325
|
+
offset = cls.__stuff_multibyte(buffer, offset, data, is_oref, locale)
|
326
|
+
return offset
|
327
|
+
|
328
|
+
@classmethod
|
329
|
+
def _stuff_datetime(cls, buffer, offset, data, locale, is_unicode, *args):
|
330
|
+
return cls._stuff_str(buffer, offset, data.strftime('%Y-%m-%d %H:%M:%S.%f'), locale=locale, is_unicode=is_unicode)
|
331
|
+
|
332
|
+
@classmethod
|
333
|
+
def _stuff_date(cls, buffer, offset, data, locale, is_unicode, *args):
|
334
|
+
return cls._stuff_str(buffer, offset, data.strftime('%Y-%m-%d'), locale=locale, is_unicode=is_unicode)
|
335
|
+
|
336
|
+
@classmethod
|
337
|
+
def _stuff_time(cls, buffer, offset, data, locale, is_unicode, *args):
|
338
|
+
return cls._stuff_str(buffer, offset, data.strftime('%H:%M:%S.%f'), locale=locale, is_unicode=is_unicode)
|
339
|
+
|
340
|
+
@classmethod
|
341
|
+
def __set_list_length_type(cls, buffer, offset, length, type):
|
342
|
+
length += 1
|
343
|
+
if length < 0xFF:
|
344
|
+
length += 1;
|
345
|
+
buffer[offset] = length
|
346
|
+
buffer[offset + 1] = type
|
347
|
+
return offset + 2
|
348
|
+
if length <= 0xFFFF:
|
349
|
+
buffer[offset] = 0
|
350
|
+
buffer[offset + 1] = length & 0xFF
|
351
|
+
buffer[offset + 2] = (length >> 8) & 0xFF
|
352
|
+
buffer[offset + 3] = type
|
353
|
+
return offset + 4
|
354
|
+
buffer[offset] = 0;
|
355
|
+
buffer[offset + 1] = 0;
|
356
|
+
buffer[offset + 2] = 0;
|
357
|
+
buffer[offset + 3] = length & 0xFF
|
358
|
+
buffer[offset + 4] = (length >> 8) & 0xFF
|
359
|
+
buffer[offset + 5] = (length >> 16) & 0xFF
|
360
|
+
buffer[offset + 6] = (length >> 24) & 0xFF
|
361
|
+
buffer[offset + 7] = type
|
362
|
+
return offset + 8
|
363
|
+
|
364
|
+
@classmethod
|
365
|
+
def __get_pos_int_length(cls, data):
|
366
|
+
if data <= 0xFF:
|
367
|
+
return 1
|
368
|
+
if data <= 0xFFFF:
|
369
|
+
return 2
|
370
|
+
if data <= 0xFFFFFF:
|
371
|
+
return 3
|
372
|
+
if data <= 0xFFFFFFFF:
|
373
|
+
return 4
|
374
|
+
if data <= 0xFFFFFFFFFF:
|
375
|
+
return 5
|
376
|
+
if data <= 0xFFFFFFFFFFFF:
|
377
|
+
return 6
|
378
|
+
if data <= 0xFFFFFFFFFFFFFF:
|
379
|
+
return 7
|
380
|
+
if data <= 0xFFFFFFFFFFFFFFFF:
|
381
|
+
return 8
|
382
|
+
raise Exception("Integer out of range")
|
383
|
+
|
384
|
+
@classmethod
|
385
|
+
def __get_neg_int_length(cls, data):
|
386
|
+
if data == -1:
|
387
|
+
return 0
|
388
|
+
if data >= -0x100:
|
389
|
+
return 1
|
390
|
+
if data >= -0x10000:
|
391
|
+
return 2
|
392
|
+
if data >= -0x1000000:
|
393
|
+
return 3
|
394
|
+
if data >= -0x100000000:
|
395
|
+
return 4
|
396
|
+
if data >= -0x10000000000:
|
397
|
+
return 5
|
398
|
+
if data >= -0x1000000000000:
|
399
|
+
return 6
|
400
|
+
if data >= -0x100000000000000:
|
401
|
+
return 7
|
402
|
+
if data >= -0x10000000000000000:
|
403
|
+
return 8
|
404
|
+
raise Exception("Integer out of range")
|
405
|
+
|
406
|
+
@classmethod
|
407
|
+
def __stuff_raw_int(cls, buffer, offset, data, length):
|
408
|
+
for i in range(length):
|
409
|
+
one_byte = data & 255
|
410
|
+
data = data >> 8
|
411
|
+
buffer[offset+i] = one_byte
|
412
|
+
return offset+length
|
413
|
+
|
414
|
+
@classmethod
|
415
|
+
def __stuff_empty_string(cls, buffer, offset):
|
416
|
+
buffer[offset] = 3
|
417
|
+
buffer[offset+1] = cls.ITEM_ASCII
|
418
|
+
buffer[offset+2] = 0
|
419
|
+
return offset+3
|
420
|
+
|
421
|
+
@classmethod
|
422
|
+
def __stuff_8bit_ascii(cls, buffer, offset, data, is_oref):
|
423
|
+
try:
|
424
|
+
list_type = cls.ITEM_OREF_ASCII if is_oref else cls.ITEM_ASCII
|
425
|
+
length = len(data)
|
426
|
+
offset = cls.__set_list_length_type(buffer, offset, length, list_type)
|
427
|
+
buffer[offset:offset+length] = data.encode("latin-1")
|
428
|
+
return offset+length
|
429
|
+
except Exception as e:
|
430
|
+
return -1
|
431
|
+
|
432
|
+
@classmethod
|
433
|
+
def __stuff_unicode(cls, buffer, offset, data, is_oref):
|
434
|
+
list_type = cls.ITEM_OREF_UNICODE if is_oref else cls.ITEM_UNICODE
|
435
|
+
byte_array = bytearray(data,"utf-16LE")
|
436
|
+
length = len(byte_array)
|
437
|
+
offset = cls.__set_list_length_type(buffer, offset, length, list_type)
|
438
|
+
buffer[offset:offset+length] = byte_array[0:length]
|
439
|
+
return offset+length
|
440
|
+
|
441
|
+
@classmethod
|
442
|
+
def __stuff_multibyte(cls, buffer, offset, data, is_oref, locale):
|
443
|
+
list_type = cls.ITEM_OREF_ASCII if is_oref else cls.ITEM_ASCII
|
444
|
+
ascii = data.encode(locale)
|
445
|
+
length = len(ascii)
|
446
|
+
offset = cls.__set_list_length_type(buffer, offset, length, list_type)
|
447
|
+
buffer[offset:offset+length] = ascii
|
448
|
+
return offset + length
|
449
|
+
|
450
|
+
@classmethod
|
451
|
+
def __parse_decimal(cls, scale, num):
|
452
|
+
decstr = str(num) + "E" + str(scale)
|
453
|
+
dec = decimal.Decimal(decstr)
|
454
|
+
return dec
|
455
|
+
|
456
|
+
@classmethod
|
457
|
+
def __get_bitlength(cls, value):
|
458
|
+
if value < 0:
|
459
|
+
return (value + 1).bit_length()
|
460
|
+
else:
|
461
|
+
return value.bit_length()
|
462
|
+
|
463
|
+
@classmethod
|
464
|
+
def _set_type_as_pass_by_reference(cls, buffer, offset):
|
465
|
+
if buffer[offset] == 0:
|
466
|
+
buffer[offset+3] = buffer[offset+3]+32
|
467
|
+
elif buffer[offset] == 1:
|
468
|
+
pass
|
469
|
+
else:
|
470
|
+
buffer[offset+1] = buffer[offset+1]+32
|
471
|
+
return
|
472
|
+
|
473
|
+
_DBList._get_switcher = {
|
474
|
+
_DBList.ITEM_ASCII: _DBList._grab_ascii_string,
|
475
|
+
_DBList.ITEM_UNICODE: _DBList._grab_unicode_string,
|
476
|
+
_DBList.ITEM_POSINT: _DBList._grab_pos_integer,
|
477
|
+
_DBList.ITEM_NEGINT: _DBList._grab_neg_integer,
|
478
|
+
_DBList.ITEM_POSNUM: _DBList._grab_pos_number,
|
479
|
+
_DBList.ITEM_NEGNUM: _DBList._grab_neg_number,
|
480
|
+
_DBList.ITEM_DOUBLE: _DBList._grab_double,
|
481
|
+
_DBList.ITEM_COMPACT_DOUBLE: _DBList._grab_compact_double,
|
482
|
+
_DBList.ITEM_OREF_ASCII: _DBList._grab_oref_ascii,
|
483
|
+
_DBList.ITEM_OREF_UNICODE: _DBList._grab_oref_unicode
|
484
|
+
}
|
485
|
+
|
486
|
+
_DBList._set_switcher = {
|
487
|
+
type(None): _DBList._stuff_null,
|
488
|
+
datetime.time: _DBList._stuff_time,
|
489
|
+
datetime.date: _DBList._stuff_date,
|
490
|
+
datetime.datetime: _DBList._stuff_datetime,
|
491
|
+
bytes: _DBList._stuff_bytes,
|
492
|
+
bytearray: _DBList._stuff_bytes,
|
493
|
+
bool: _DBList._stuff_int,
|
494
|
+
int: _DBList._stuff_int,
|
495
|
+
float: _DBList._stuff_double,
|
496
|
+
decimal.Decimal: _DBList._stuff_decimal,
|
497
|
+
str: _DBList._stuff_str,
|
498
|
+
intersystems_iris._IRISOREF._IRISOREF: _DBList._stuff_str,
|
499
|
+
}
|