sqlalchemy-iris 0.5.0b3__tar.gz → 0.6.0b1__tar.gz

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.
Files changed (95) hide show
  1. {sqlalchemy-iris-0.5.0b3/sqlalchemy_iris.egg-info → sqlalchemy-iris-0.6.0b1}/PKG-INFO +1 -1
  2. sqlalchemy-iris-0.6.0b1/intersystems_iris/_BufferReader.py +10 -0
  3. sqlalchemy-iris-0.6.0b1/intersystems_iris/_BufferWriter.py +32 -0
  4. sqlalchemy-iris-0.6.0b1/intersystems_iris/_ConnectionInformation.py +54 -0
  5. sqlalchemy-iris-0.6.0b1/intersystems_iris/_ConnectionParameters.py +18 -0
  6. sqlalchemy-iris-0.6.0b1/intersystems_iris/_Constant.py +38 -0
  7. sqlalchemy-iris-0.6.0b1/intersystems_iris/_DBList.py +499 -0
  8. sqlalchemy-iris-0.6.0b1/intersystems_iris/_Device.py +69 -0
  9. sqlalchemy-iris-0.6.0b1/intersystems_iris/_GatewayContext.py +25 -0
  10. sqlalchemy-iris-0.6.0b1/intersystems_iris/_GatewayException.py +4 -0
  11. sqlalchemy-iris-0.6.0b1/intersystems_iris/_GatewayUtility.py +74 -0
  12. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRIS.py +1294 -0
  13. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISConnection.py +516 -0
  14. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISEmbedded.py +85 -0
  15. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISGlobalNode.py +273 -0
  16. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISGlobalNodeView.py +25 -0
  17. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISIterator.py +143 -0
  18. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISList.py +360 -0
  19. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISNative.py +208 -0
  20. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISOREF.py +4 -0
  21. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISObject.py +424 -0
  22. sqlalchemy-iris-0.6.0b1/intersystems_iris/_IRISReference.py +133 -0
  23. sqlalchemy-iris-0.6.0b1/intersystems_iris/_InStream.py +149 -0
  24. sqlalchemy-iris-0.6.0b1/intersystems_iris/_LegacyIterator.py +135 -0
  25. sqlalchemy-iris-0.6.0b1/intersystems_iris/_ListItem.py +15 -0
  26. sqlalchemy-iris-0.6.0b1/intersystems_iris/_ListReader.py +84 -0
  27. sqlalchemy-iris-0.6.0b1/intersystems_iris/_ListWriter.py +157 -0
  28. sqlalchemy-iris-0.6.0b1/intersystems_iris/_LogFileStream.py +115 -0
  29. sqlalchemy-iris-0.6.0b1/intersystems_iris/_MessageHeader.py +51 -0
  30. sqlalchemy-iris-0.6.0b1/intersystems_iris/_OutStream.py +25 -0
  31. sqlalchemy-iris-0.6.0b1/intersystems_iris/_PrintStream.py +65 -0
  32. sqlalchemy-iris-0.6.0b1/intersystems_iris/_PythonGateway.py +850 -0
  33. sqlalchemy-iris-0.6.0b1/intersystems_iris/_SharedMemorySocket.py +87 -0
  34. sqlalchemy-iris-0.6.0b1/intersystems_iris/__init__.py +79 -0
  35. sqlalchemy-iris-0.6.0b1/intersystems_iris/__main__.py +7 -0
  36. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_Column.py +56 -0
  37. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_DBAPI.py +2295 -0
  38. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_Descriptor.py +46 -0
  39. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_IRISStream.py +63 -0
  40. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_Message.py +158 -0
  41. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_Parameter.py +138 -0
  42. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_ParameterCollection.py +133 -0
  43. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_ResultSetRow.py +314 -0
  44. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/_SQLType.py +32 -0
  45. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/__init__.py +0 -0
  46. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/preparser/_PreParser.py +1658 -0
  47. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/preparser/_Scanner.py +391 -0
  48. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/preparser/_Token.py +81 -0
  49. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/preparser/_TokenList.py +251 -0
  50. sqlalchemy-iris-0.6.0b1/intersystems_iris/dbapi/preparser/__init__.py +0 -0
  51. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_BusinessHost.py +101 -0
  52. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_BusinessOperation.py +105 -0
  53. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_BusinessProcess.py +214 -0
  54. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_BusinessService.py +95 -0
  55. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_Common.py +228 -0
  56. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_Director.py +24 -0
  57. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_IRISBusinessOperation.py +5 -0
  58. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_IRISBusinessService.py +18 -0
  59. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_IRISInboundAdapter.py +5 -0
  60. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_IRISOutboundAdapter.py +17 -0
  61. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_InboundAdapter.py +57 -0
  62. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_Message.py +6 -0
  63. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/_OutboundAdapter.py +46 -0
  64. sqlalchemy-iris-0.6.0b1/intersystems_iris/pex/__init__.py +25 -0
  65. sqlalchemy-iris-0.6.0b1/iris/__init__.py +25 -0
  66. sqlalchemy-iris-0.6.0b1/iris/iris_site.py +13 -0
  67. sqlalchemy-iris-0.6.0b1/iris/irisbuiltins.py +97 -0
  68. sqlalchemy-iris-0.6.0b1/iris/irisloader.py +199 -0
  69. sqlalchemy-iris-0.6.0b1/irisnative/_IRISNative.py +9 -0
  70. sqlalchemy-iris-0.6.0b1/irisnative/__init__.py +10 -0
  71. sqlalchemy-iris-0.6.0b1/requirements-iris.txt +1 -0
  72. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/setup.cfg +1 -1
  73. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1/sqlalchemy_iris.egg-info}/PKG-INFO +1 -1
  74. sqlalchemy-iris-0.6.0b1/sqlalchemy_iris.egg-info/SOURCES.txt +92 -0
  75. sqlalchemy-iris-0.6.0b1/sqlalchemy_iris.egg-info/top_level.txt +4 -0
  76. sqlalchemy-iris-0.5.0b3/sqlalchemy_iris.egg-info/SOURCES.txt +0 -22
  77. sqlalchemy-iris-0.5.0b3/sqlalchemy_iris.egg-info/top_level.txt +0 -1
  78. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/LICENSE +0 -0
  79. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/MANIFEST.in +0 -0
  80. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/README.md +0 -0
  81. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/requirements-dev.txt +0 -0
  82. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/requirements.txt +0 -0
  83. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/setup.py +0 -0
  84. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/__init__.py +0 -0
  85. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/base.py +0 -0
  86. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/embedded.py +0 -0
  87. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/information_schema.py +0 -0
  88. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/iris.py +0 -0
  89. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/provision.py +0 -0
  90. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/requirements.py +0 -0
  91. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris/types.py +0 -0
  92. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris.egg-info/dependency_links.txt +0 -0
  93. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris.egg-info/entry_points.txt +0 -0
  94. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/sqlalchemy_iris.egg-info/requires.txt +0 -0
  95. {sqlalchemy-iris-0.5.0b3 → sqlalchemy-iris-0.6.0b1}/tests/test_suite.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlalchemy-iris
3
- Version: 0.5.0b3
3
+ Version: 0.6.0b1
4
4
  Summary: InterSystems IRIS for SQLAlchemy
5
5
  Home-page: https://github.com/caretdev/sqlalchemy-iris
6
6
  Maintainer: CaretDev
@@ -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
+ }