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,135 @@
|
|
1
|
+
import collections.abc
|
2
|
+
import intersystems_iris._IRISIterator
|
3
|
+
|
4
|
+
class _LegacyIterator(collections.abc.Iterator, collections.abc.Iterable):
|
5
|
+
'''
|
6
|
+
This class has been deprecated. Please call IRIS.node() in order to use IRISGlobalNode instead.
|
7
|
+
|
8
|
+
LegacyIterator is an iterator over the immediate children of a global node.
|
9
|
+
|
10
|
+
The iterator can be set to move forwards or backwards, and to return the subscript and value, just the subscript, or just the value for each node in the iteration. This is similar to using the $ORDER function in ObjectScript.
|
11
|
+
'''
|
12
|
+
|
13
|
+
def __init__(self, irisnative, global_name, *subscripts):
|
14
|
+
self._irisnative = irisnative
|
15
|
+
self._global_name = global_name
|
16
|
+
self._subscripts = subscripts
|
17
|
+
self._start_from = None
|
18
|
+
self._reversed = False
|
19
|
+
self._view_type = intersystems_iris.IRISIterator.VIEW_ITEMS
|
20
|
+
self._at_end = False
|
21
|
+
|
22
|
+
def __iter__(self):
|
23
|
+
return self
|
24
|
+
|
25
|
+
def __next__(self):
|
26
|
+
return self.next()
|
27
|
+
|
28
|
+
def next(self):
|
29
|
+
if self._at_end:
|
30
|
+
raise StopIteration
|
31
|
+
key_value = self._irisnative._nextNode(self._reversed, self._global_name, *self._subscripts, self._start_from)
|
32
|
+
# check if we are at end
|
33
|
+
returned_value = key_value[0]
|
34
|
+
if returned_value == None or len(returned_value) == 0:
|
35
|
+
self._at_end = True
|
36
|
+
raise StopIteration
|
37
|
+
self._start_from = returned_value
|
38
|
+
# return value
|
39
|
+
if self._view_type == intersystems_iris.IRISIterator.VIEW_SUBSCRIPTS:
|
40
|
+
return key_value[0]
|
41
|
+
elif self._view_type == intersystems_iris.IRISIterator.VIEW_VALUES:
|
42
|
+
return key_value[1]
|
43
|
+
elif self._view_type == intersystems_iris.IRISIterator.VIEW_ITEMS:
|
44
|
+
return key_value
|
45
|
+
else:
|
46
|
+
raise TypeError("Unrecognized view type")
|
47
|
+
|
48
|
+
def startFrom(self, subscript):
|
49
|
+
'''
|
50
|
+
Set the starting position and return the iterator.
|
51
|
+
|
52
|
+
startFrom(subscript)
|
53
|
+
|
54
|
+
Set the starting position to the specified subscript. After calling this
|
55
|
+
method, use next() to advance the iterator to the next defined sub-node
|
56
|
+
in alphabetic collating sequence. For example, for the following global
|
57
|
+
and iterator:
|
58
|
+
^gbl("a")=11
|
59
|
+
^gbl("b")=22
|
60
|
+
^gbl("e")=55
|
61
|
+
itr=iris.iterator("^gbl")
|
62
|
+
The starting position may be a valid sub-node, in which case the next sub-node will be the next valid one.
|
63
|
+
itr.startFrom("a")
|
64
|
+
for sub, val in itr:
|
65
|
+
print(sub,"->",val)
|
66
|
+
// prints: b -> 22; e -> 55
|
67
|
+
The starting position may also be an invalid sub-node, in which case the next sub-node will be the first valid one in alphabetic collating sequence after the given subscript.
|
68
|
+
itr.startFrom("c")
|
69
|
+
for sub, val in itr:
|
70
|
+
print(sub,"->",val)
|
71
|
+
// prints: e -> 55
|
72
|
+
Calling this method with None as the argument is the same as using the default starting position, which is just before the first node, or just after the last node, depending on the iterator direction.
|
73
|
+
|
74
|
+
Parameters
|
75
|
+
----------
|
76
|
+
subscript : a single subscript indicating a starting position
|
77
|
+
|
78
|
+
Returns
|
79
|
+
-------
|
80
|
+
The same iterator object.
|
81
|
+
'''
|
82
|
+
self._start_from = subscript
|
83
|
+
return self
|
84
|
+
|
85
|
+
def reversed(self):
|
86
|
+
'''
|
87
|
+
Reverse the direction and return the iterator.
|
88
|
+
|
89
|
+
reversed()
|
90
|
+
|
91
|
+
Returns
|
92
|
+
-------
|
93
|
+
The same iterator object.
|
94
|
+
'''
|
95
|
+
self._reversed = not self._reversed
|
96
|
+
return self
|
97
|
+
|
98
|
+
def subscripts(self):
|
99
|
+
''''
|
100
|
+
Set the iterator to return subscripts only and return the iterator.
|
101
|
+
|
102
|
+
subscripts()
|
103
|
+
|
104
|
+
Returns
|
105
|
+
-------
|
106
|
+
The same iterator object.
|
107
|
+
'''
|
108
|
+
self._view_type = intersystems_iris.IRISIterator.VIEW_SUBSCRIPTS
|
109
|
+
return self
|
110
|
+
|
111
|
+
def values(self):
|
112
|
+
'''
|
113
|
+
Set the iterator to return values only and return the iterator.
|
114
|
+
|
115
|
+
values()
|
116
|
+
|
117
|
+
Returns
|
118
|
+
-------
|
119
|
+
The same iterator object.
|
120
|
+
'''
|
121
|
+
self._view_type = intersystems_iris.IRISIterator.VIEW_VALUES
|
122
|
+
return self
|
123
|
+
|
124
|
+
def items(self):
|
125
|
+
'''
|
126
|
+
Set the iterator to return subscript and value tuples, and return the iterator.
|
127
|
+
|
128
|
+
items()
|
129
|
+
|
130
|
+
Returns
|
131
|
+
-------
|
132
|
+
The same iterator object.
|
133
|
+
'''
|
134
|
+
self._view_type = intersystems_iris.IRISIterator.VIEW_ITEMS
|
135
|
+
return self
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import intersystems_iris._DBList
|
2
|
+
|
3
|
+
class _ListItem(object):
|
4
|
+
|
5
|
+
def __init__(self, buffer):
|
6
|
+
self.buffer = buffer
|
7
|
+
self.list_buffer_end = len(buffer)
|
8
|
+
self.is_null = False
|
9
|
+
self.type = intersystems_iris._DBList._DBList.ITEM_PLACEHOLDER
|
10
|
+
self.data_offset = 0
|
11
|
+
self.data_length = 0
|
12
|
+
self.next_offset = 0
|
13
|
+
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import intersystems_iris._DBList
|
2
|
+
import intersystems_iris._ListItem
|
3
|
+
|
4
|
+
|
5
|
+
class _ListReader(object):
|
6
|
+
|
7
|
+
def __init__(self, bufferarray, locale="latin-1"):
|
8
|
+
self.list_item = intersystems_iris._ListItem._ListItem(bufferarray)
|
9
|
+
self._locale = locale
|
10
|
+
|
11
|
+
def __iter__(self):
|
12
|
+
return self
|
13
|
+
|
14
|
+
def __next__(self):
|
15
|
+
if self._is_end():
|
16
|
+
raise StopIteration
|
17
|
+
else:
|
18
|
+
return self._get()
|
19
|
+
|
20
|
+
def _get(self, asBytes=False, retainAsciiZero=False):
|
21
|
+
intersystems_iris._DBList._DBList._get_list_element(self.list_item)
|
22
|
+
return intersystems_iris._DBList._DBList._get(self.list_item, self._locale, asBytes, retainAsciiZero)
|
23
|
+
|
24
|
+
def get_inner_list(self):
|
25
|
+
ba = self._get(True)
|
26
|
+
if not ba:
|
27
|
+
return None
|
28
|
+
return _ListReader(ba, self._locale)
|
29
|
+
|
30
|
+
def _get_raw_bytes(self, length):
|
31
|
+
self.is_null = False
|
32
|
+
self.list_item.type = intersystems_iris._DBList._DBList.ITEM_PLACEHOLDER
|
33
|
+
self.list_item.data_offset = 0
|
34
|
+
self.list_item.data_length = 0
|
35
|
+
self.list_item.next_offset = self.list_item.next_offset + length
|
36
|
+
return self.list_item.buffer[self.list_item.next_offset - length:self.list_item.next_offset]
|
37
|
+
|
38
|
+
def _get_raw(self):
|
39
|
+
return self.list_item.buffer
|
40
|
+
|
41
|
+
def _is_end(self):
|
42
|
+
return (self.list_item.next_offset >= self.list_item.list_buffer_end)
|
43
|
+
def _get_at_offset(self, offset, asBytes = False):
|
44
|
+
self.list_item.next_offset = offset
|
45
|
+
intersystems_iris._DBList._DBList._get_list_element(self.list_item)
|
46
|
+
return intersystems_iris._DBList._DBList._get(self.list_item, self._locale, asBytes)
|
47
|
+
|
48
|
+
def _move_to_end(self):
|
49
|
+
self.list_item.next_offset = self.list_item.list_buffer_end
|
50
|
+
|
51
|
+
def _get_offset(self):
|
52
|
+
return self.list_item.next_offset
|
53
|
+
|
54
|
+
def _next(self):
|
55
|
+
return intersystems_iris._DBList._DBList._get_list_element(self.list_item)
|
56
|
+
|
57
|
+
def _get_output_parameter_list(self, begin, add_null):
|
58
|
+
len = self.list_item.next_offset - begin
|
59
|
+
offset = 3 if add_null else 0
|
60
|
+
ba = bytearray(len + offset)
|
61
|
+
if add_null:
|
62
|
+
quote_quote = bytearray([3, 1, 0])
|
63
|
+
ba = quote_quote
|
64
|
+
ba[offset:len] = self.list_item.buffer[begin:len]
|
65
|
+
return intersystems_iris._ListReader._ListReader(ba, self._locale)
|
66
|
+
|
67
|
+
def _is_past_last_item(self):
|
68
|
+
return (self.list_item.data_offset >= self.list_item.list_buffer_end)
|
69
|
+
|
70
|
+
def _is_undefined(self):
|
71
|
+
return (self.list_item.type == intersystems_iris._DBList._DBList.ITEM_UNDEF)
|
72
|
+
|
73
|
+
def _next_unless_undefined(self):
|
74
|
+
self._next()
|
75
|
+
if self._is_past_last_item():
|
76
|
+
raise Exception("No more data")
|
77
|
+
if self._is_undefined():
|
78
|
+
raise Exception("Output/Default parameter not assigned a value")
|
79
|
+
return
|
80
|
+
|
81
|
+
def _clear_list(self):
|
82
|
+
self.list_item.list_buffer_end = 0
|
83
|
+
self.list_item.next_offset = 0
|
84
|
+
return
|
@@ -0,0 +1,157 @@
|
|
1
|
+
import datetime
|
2
|
+
import decimal
|
3
|
+
import intersystems_iris._DBList
|
4
|
+
import intersystems_iris.dbapi._DBAPI
|
5
|
+
from .dbapi._SQLType import SQLType
|
6
|
+
class _ListWriter(object):
|
7
|
+
|
8
|
+
CHUNKSIZE = 256
|
9
|
+
|
10
|
+
def __init__(self, locale = "latin-1", is_unicode = True, compact_double = False):
|
11
|
+
self.buffer = bytearray(self.CHUNKSIZE)
|
12
|
+
self.offset = 0
|
13
|
+
self._locale = locale
|
14
|
+
self._is_unicode = is_unicode
|
15
|
+
self._compact_double = compact_double
|
16
|
+
|
17
|
+
def _clear_list(self):
|
18
|
+
self.offset = 0
|
19
|
+
|
20
|
+
def _set(self, data, retainEmptyString=False):
|
21
|
+
if retainEmptyString and type(data) == str and len(data) == 0:
|
22
|
+
self._set_null()
|
23
|
+
else:
|
24
|
+
self.__check_buffer_size(self.__estimate_size(data))
|
25
|
+
self.offset = intersystems_iris._DBList._DBList._set(self.buffer, self.offset, data, self._locale, self._is_unicode, self._compact_double)
|
26
|
+
return
|
27
|
+
|
28
|
+
def _set_list(self, data):
|
29
|
+
if data is None:
|
30
|
+
self._set_null()
|
31
|
+
else:
|
32
|
+
self.__check_buffer_size(data.offset)
|
33
|
+
self.offset = intersystems_iris._DBList._DBList._stuff_bytes(self.buffer, self.offset, data._get_buffer())
|
34
|
+
|
35
|
+
def _set_undefined(self):
|
36
|
+
self.__check_buffer_size(1)
|
37
|
+
self.offset = intersystems_iris._DBList._DBList._set_undefined(self.buffer, self.offset)
|
38
|
+
|
39
|
+
def _set_null(self):
|
40
|
+
self.__check_buffer_size(2)
|
41
|
+
self.offset = intersystems_iris._DBList._DBList._set_null(self.buffer, self.offset)
|
42
|
+
|
43
|
+
def _set_raw_bytes(self, data):
|
44
|
+
length = len(data)
|
45
|
+
self.__check_buffer_size(length)
|
46
|
+
self.buffer[self.offset:self.offset+length] = data[0:length]
|
47
|
+
self.offset = self.offset + length
|
48
|
+
return
|
49
|
+
|
50
|
+
def _set_parameter(self, param):
|
51
|
+
param_switcher = {
|
52
|
+
SQLType.LONGVARBINARY: self._set_stream,
|
53
|
+
SQLType.LONGVARCHAR: self._set_stream,
|
54
|
+
SQLType.DATE: None,
|
55
|
+
SQLType.TIME: None,
|
56
|
+
SQLType.TIMESTAMP: None,
|
57
|
+
SQLType.TYPE_DATE: None,
|
58
|
+
SQLType.TYPE_TIME: None,
|
59
|
+
SQLType.TYPE_TIMESTAMP: None,
|
60
|
+
SQLType.DATE_HOROLOG: self._set_date_h,
|
61
|
+
SQLType.TIME_HOROLOG: self._set_time_h,
|
62
|
+
SQLType.TIMESTAMP_POSIX: self._set_posix
|
63
|
+
}
|
64
|
+
param_func = param_switcher.get(param.type, None)
|
65
|
+
if param_func is None:
|
66
|
+
self._set(param.value)
|
67
|
+
else:
|
68
|
+
param_func(param.value)
|
69
|
+
|
70
|
+
def _set_parameter_type(self, param_type, value):
|
71
|
+
param_switcher = {
|
72
|
+
SQLType.LONGVARBINARY: self._set_stream,
|
73
|
+
SQLType.LONGVARCHAR: self._set_stream,
|
74
|
+
SQLType.DATE: None,
|
75
|
+
SQLType.TIME: None,
|
76
|
+
SQLType.TIMESTAMP: None,
|
77
|
+
SQLType.TYPE_DATE: None,
|
78
|
+
SQLType.TYPE_TIME: None,
|
79
|
+
SQLType.TYPE_TIMESTAMP: None,
|
80
|
+
SQLType.DATE_HOROLOG: self._set_date_h,
|
81
|
+
SQLType.TIME_HOROLOG: self._set_time_h,
|
82
|
+
SQLType.TIMESTAMP_POSIX: self._set_posix
|
83
|
+
}
|
84
|
+
param_func = param_switcher.get(param_type, None)
|
85
|
+
if param_func is None:
|
86
|
+
self._set(value)
|
87
|
+
else:
|
88
|
+
param_func(value)
|
89
|
+
|
90
|
+
def _set_stream(self, stream):
|
91
|
+
self._set(stream)
|
92
|
+
# raise NotImplementedError("Stream functionality not yet available with iris.dbapi")
|
93
|
+
|
94
|
+
def _set_date_h(self, date):
|
95
|
+
HOROLOG_ORDINAL = datetime.date(1840, 12, 31).toordinal()
|
96
|
+
if isinstance(date, datetime.date):
|
97
|
+
date_h = date.toordinal() - HOROLOG_ORDINAL
|
98
|
+
self._set(date_h)
|
99
|
+
else:
|
100
|
+
self._set(date)
|
101
|
+
|
102
|
+
def _set_time_h(self, time):
|
103
|
+
if isinstance(time, datetime.time) or isinstance(time, datetime.datetime):
|
104
|
+
time_h = 3600 * time.hour + 60 * time.minute + time.second
|
105
|
+
self._set(time_h)
|
106
|
+
else:
|
107
|
+
self._set(time)
|
108
|
+
|
109
|
+
def _set_posix(self, timestamp):
|
110
|
+
if isinstance(timestamp, datetime.datetime):
|
111
|
+
self._set(timestamp.strftime('%Y-%m-%d %H:%M:%S.%f'))
|
112
|
+
else:
|
113
|
+
self._set(timestamp)
|
114
|
+
|
115
|
+
def _size(self):
|
116
|
+
return self.offset
|
117
|
+
|
118
|
+
def _get_buffer(self):
|
119
|
+
return self.buffer[0:self.offset]
|
120
|
+
|
121
|
+
def __estimate_size(self, data):
|
122
|
+
if type(data) == int and (data > 0x7fffffffffffffff or data < -0x8000000000000000):
|
123
|
+
data = str(data)
|
124
|
+
if type(data) is str or type(data) is bytes or type(data) is bytearray:
|
125
|
+
estimated = len(data)*2+8
|
126
|
+
else:
|
127
|
+
estimated = self._estimate_size_switcher.get(type(data), 0)
|
128
|
+
return estimated
|
129
|
+
|
130
|
+
def __check_buffer_size(self, additional):
|
131
|
+
if self.offset + additional > len(self.buffer):
|
132
|
+
size_needed = self.offset + additional
|
133
|
+
size_to_allocate = len(self.buffer)*2
|
134
|
+
while True:
|
135
|
+
if size_to_allocate > size_needed:
|
136
|
+
break
|
137
|
+
size_to_allocate = size_to_allocate*2
|
138
|
+
new_buffer = bytearray(size_to_allocate)
|
139
|
+
new_buffer[0:len(self.buffer)] = self.buffer
|
140
|
+
self.buffer = new_buffer
|
141
|
+
return
|
142
|
+
|
143
|
+
def _save_current_offset(self):
|
144
|
+
self.__saved_offset = self.offset
|
145
|
+
return
|
146
|
+
|
147
|
+
def _set_saved_offset_type_as_pass_by_reference(self):
|
148
|
+
intersystems_iris._DBList._DBList._set_type_as_pass_by_reference(self.buffer, self.__saved_offset)
|
149
|
+
return
|
150
|
+
|
151
|
+
_ListWriter._estimate_size_switcher = {
|
152
|
+
type(None): 2,
|
153
|
+
bool: 3,
|
154
|
+
int: 10,
|
155
|
+
float: 10,
|
156
|
+
decimal.Decimal: 11
|
157
|
+
}
|
@@ -0,0 +1,115 @@
|
|
1
|
+
import io
|
2
|
+
import os
|
3
|
+
import datetime
|
4
|
+
import threading
|
5
|
+
import platform
|
6
|
+
|
7
|
+
class _LogFileStream(object):
|
8
|
+
|
9
|
+
LOG_RECEIVED = 0
|
10
|
+
LOG_SENT = 1
|
11
|
+
LINE_SEPARATOR = '\n'
|
12
|
+
BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE
|
13
|
+
|
14
|
+
def __init__(self, path):
|
15
|
+
b_new_file = False
|
16
|
+
if (path.startswith("+")):
|
17
|
+
b_new_file = True
|
18
|
+
path = path[1:]
|
19
|
+
if (path.startswith("-")):
|
20
|
+
self.b_skip_logging = True
|
21
|
+
path = path[1:]
|
22
|
+
if b_new_file and os.path.exists(path):
|
23
|
+
os.remove(path)
|
24
|
+
self.path = path
|
25
|
+
self.bytesPerLine = 14 if os.path.splitext(path)[0].endswith("14") else 16
|
26
|
+
self.__dump_start()
|
27
|
+
|
28
|
+
def __dump_start(self):
|
29
|
+
with open(self.path, 'a') as f:
|
30
|
+
f.write(
|
31
|
+
self.LINE_SEPARATOR
|
32
|
+
+ "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
|
33
|
+
f.write(
|
34
|
+
self.LINE_SEPARATOR
|
35
|
+
+ "\tStarted At: " + datetime.datetime.now().strftime("%b %d, %Y %I:%M:%S %p"))
|
36
|
+
f.write(
|
37
|
+
self.LINE_SEPARATOR
|
38
|
+
+ "\tPython Version: " + platform.python_version())
|
39
|
+
f.write(
|
40
|
+
self.LINE_SEPARATOR
|
41
|
+
+ "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
|
42
|
+
+ self.LINE_SEPARATOR)
|
43
|
+
|
44
|
+
def __dump_info(self, type, connection):
|
45
|
+
if type == self.LOG_SENT:
|
46
|
+
type_text = "Sent"
|
47
|
+
else:
|
48
|
+
type_text = "Received"
|
49
|
+
with open(self.path, 'a') as f:
|
50
|
+
f.write(
|
51
|
+
self.LINE_SEPARATOR + type_text + ": ("
|
52
|
+
+ datetime.datetime.now().strftime("%H:%M:%S:%f")[:-3] + ")"
|
53
|
+
+ " [ThreadID = " + str(threading.get_ident()) + " ]"
|
54
|
+
+ " [JobNumber = " + str(connection._connection_info._server_job_number) + " ]"
|
55
|
+
+ " [DeviceID = " + str(id(connection._device)) + " ]"
|
56
|
+
+ self.LINE_SEPARATOR)
|
57
|
+
|
58
|
+
def _logApi(self, text):
|
59
|
+
with open(self.path, 'a') as f:
|
60
|
+
f.write(self.LINE_SEPARATOR + text + self.LINE_SEPARATOR)
|
61
|
+
|
62
|
+
def _dump_header(self, buffer, type, connection):
|
63
|
+
if buffer is None:
|
64
|
+
return
|
65
|
+
self.__dump_info(type, connection)
|
66
|
+
line = "Header:"
|
67
|
+
self._dump(line, buffer, False)
|
68
|
+
|
69
|
+
def _dump_message(self, buffer):
|
70
|
+
if buffer is None:
|
71
|
+
return
|
72
|
+
line = "Message:"
|
73
|
+
self._dump(line, buffer, True)
|
74
|
+
|
75
|
+
def _dump(self, line, buffer, is_message):
|
76
|
+
asciistr = ""
|
77
|
+
i = 0
|
78
|
+
f = open(self.path, 'a')
|
79
|
+
while i < len(buffer):
|
80
|
+
if i % self.bytesPerLine == 0:
|
81
|
+
if i != 0:
|
82
|
+
line += " "
|
83
|
+
line += asciistr + self.LINE_SEPARATOR
|
84
|
+
asciistr = ""
|
85
|
+
line += _LogFileStream.__format_offset(i)
|
86
|
+
x = '{:02X}'.format(int(buffer[i]))
|
87
|
+
asciistr += _LogFileStream.__convert_to_ascii(int(buffer[i]))
|
88
|
+
line += " " + x + " "
|
89
|
+
if i % _LogFileStream.BUFFER_SIZE == 0:
|
90
|
+
f.write(line)
|
91
|
+
line = ""
|
92
|
+
i += 1
|
93
|
+
line += self.__format_last_line(i)
|
94
|
+
line += " " + asciistr + self.LINE_SEPARATOR
|
95
|
+
if is_message:
|
96
|
+
line += self.LINE_SEPARATOR
|
97
|
+
f.write(line)
|
98
|
+
f.close()
|
99
|
+
|
100
|
+
@staticmethod
|
101
|
+
def __format_offset(value):
|
102
|
+
return ' {:04X}: '.format(value)
|
103
|
+
|
104
|
+
@staticmethod
|
105
|
+
def __convert_to_ascii(value):
|
106
|
+
if value >= 32 and value < 127:
|
107
|
+
return chr(value)
|
108
|
+
return "."
|
109
|
+
|
110
|
+
def __format_last_line(self, count):
|
111
|
+
spaces = ""
|
112
|
+
while count % self.bytesPerLine != 0:
|
113
|
+
spaces += " "
|
114
|
+
count += 1
|
115
|
+
return spaces
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class _MessageHeader(object):
|
2
|
+
|
3
|
+
HEADER_SIZE = 14
|
4
|
+
|
5
|
+
def __init__(self):
|
6
|
+
self.buffer = bytearray(self.HEADER_SIZE)
|
7
|
+
|
8
|
+
def _get_message_length(self):
|
9
|
+
return self.__get_4_byte_int_raw(0)
|
10
|
+
|
11
|
+
def _get_message_id(self):
|
12
|
+
return self.__get_4_byte_int_raw(4)
|
13
|
+
|
14
|
+
# TODO: remove this method, use _get_message_id()
|
15
|
+
def _get_count(self):
|
16
|
+
return self.__get_4_byte_int_raw(4)
|
17
|
+
|
18
|
+
def _get_statement_id(self):
|
19
|
+
return self.__get_4_byte_int_raw(8) & ~(0x80000000)
|
20
|
+
|
21
|
+
def _get_function_code(self):
|
22
|
+
return (self.buffer[12] & 0x00FF) | ((self.buffer[13] & 0x00FF) << 8)
|
23
|
+
|
24
|
+
# TODO: remove this method, use _get_function_code()
|
25
|
+
def _get_error(self):
|
26
|
+
return (self.buffer[12] & 0x00FF) | ((self.buffer[13] & 0x00FF) << 8)
|
27
|
+
|
28
|
+
@classmethod
|
29
|
+
def _set_count(cls, buffer, value):
|
30
|
+
cls.__set_raw_4_byte_int(buffer, 4, value)
|
31
|
+
|
32
|
+
@classmethod
|
33
|
+
def _set_message_length(cls, buffer, value):
|
34
|
+
cls.__set_raw_4_byte_int(buffer, 0, value)
|
35
|
+
|
36
|
+
@classmethod
|
37
|
+
def _set_statement_id(cls, buffer, value):
|
38
|
+
cls.__set_raw_4_byte_int(buffer, 8, value)
|
39
|
+
|
40
|
+
def __get_4_byte_int_raw(self, offset):
|
41
|
+
return ((self.buffer[offset] & 0x000000FF) |
|
42
|
+
((self.buffer[offset + 1] & 0x000000FF) << 8) |
|
43
|
+
((self.buffer[offset + 2] & 0x000000FF) << 16) |
|
44
|
+
((self.buffer[offset + 3] & 0x000000FF) << 24))
|
45
|
+
|
46
|
+
@staticmethod
|
47
|
+
def __set_raw_4_byte_int(buffer, offset, value):
|
48
|
+
buffer[offset] = value & 0xFF
|
49
|
+
buffer[offset + 1] = (value >> 8) & 0xFF
|
50
|
+
buffer[offset + 2] = (value >> 16) & 0xFF
|
51
|
+
buffer[offset + 3] = (value >> 24) & 0xFF
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import intersystems_iris._BufferWriter
|
2
|
+
import intersystems_iris._LogFileStream
|
3
|
+
|
4
|
+
class _OutStream(object):
|
5
|
+
|
6
|
+
def __init__(self, connection):
|
7
|
+
self._connection = connection
|
8
|
+
self._device = connection._device
|
9
|
+
self._log_stream = connection._log_stream
|
10
|
+
self.wire = intersystems_iris._BufferWriter._BufferWriter(self._connection._connection_info._locale,self._connection._connection_info._is_unicode,self._connection._connection_info._compact_double)
|
11
|
+
|
12
|
+
def _send(self, sequence_number):
|
13
|
+
list_len = self.wire._size() - intersystems_iris._MessageHeader._MessageHeader.HEADER_SIZE
|
14
|
+
intersystems_iris._MessageHeader._MessageHeader._set_message_length(self.wire.buffer, list_len)
|
15
|
+
intersystems_iris._MessageHeader._MessageHeader._set_count(self.wire.buffer, sequence_number)
|
16
|
+
if self._device is None:
|
17
|
+
raise RuntimeError("no longer connected to server")
|
18
|
+
self._device.sendall(self.wire._get_buffer())
|
19
|
+
if self._log_stream is not None:
|
20
|
+
self._log_stream._dump_header(self.wire._get_header_buffer(), intersystems_iris._LogFileStream._LogFileStream.LOG_SENT, self._connection)
|
21
|
+
if list_len > 0:
|
22
|
+
if self._log_stream is not None:
|
23
|
+
self._log_stream._dump_message(self.wire._get_data_buffer())
|
24
|
+
return
|
25
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import io
|
2
|
+
import os
|
3
|
+
import sys
|
4
|
+
import threading
|
5
|
+
import intersystems_iris._GatewayContext
|
6
|
+
|
7
|
+
class _PrintStream(io.StringIO):
|
8
|
+
|
9
|
+
def __init__(self, type):
|
10
|
+
super().__init__()
|
11
|
+
self.hmap = {}
|
12
|
+
self.type = type
|
13
|
+
|
14
|
+
def _register(self):
|
15
|
+
thread_id = threading.get_ident()
|
16
|
+
out = ""
|
17
|
+
self.hmap[thread_id] = out
|
18
|
+
|
19
|
+
def _unregister(self):
|
20
|
+
thread_id = threading.get_ident()
|
21
|
+
self.hmap.pop(thread_id, None)
|
22
|
+
|
23
|
+
def _was_written_to(self):
|
24
|
+
output_buffer = self.__get_out_buffer()
|
25
|
+
if output_buffer is None:
|
26
|
+
return False
|
27
|
+
else:
|
28
|
+
return len(output_buffer) != 0
|
29
|
+
|
30
|
+
def __get_out_buffer(self):
|
31
|
+
thread_id = threading.get_ident()
|
32
|
+
return self.hmap.get(thread_id)
|
33
|
+
|
34
|
+
def __empty_buffer(self):
|
35
|
+
thread_id = threading.get_ident()
|
36
|
+
del self.hmap[thread_id]
|
37
|
+
self._register()
|
38
|
+
|
39
|
+
def _get_buffer_contents(self):
|
40
|
+
output_buffer = self.__get_out_buffer()
|
41
|
+
if output_buffer is None: return ""
|
42
|
+
formatted_output_buffer = "\r\n".join(output_buffer.splitlines())
|
43
|
+
if output_buffer.endswith("\n"):
|
44
|
+
formatted_output_buffer += "\r\n"
|
45
|
+
self.__empty_buffer()
|
46
|
+
return formatted_output_buffer
|
47
|
+
|
48
|
+
def write(self, value):
|
49
|
+
thread_id = threading.get_ident()
|
50
|
+
if thread_id not in self.hmap.keys():
|
51
|
+
if self.type == 0:
|
52
|
+
sys.__stdout__.write(value)
|
53
|
+
else:
|
54
|
+
sys.__stderr__.write(value)
|
55
|
+
return
|
56
|
+
try:
|
57
|
+
native = intersystems_iris.GatewayContext.getIRIS()
|
58
|
+
formatted_value = "\r\n".join(value.splitlines())
|
59
|
+
if value.endswith("\n"): formatted_value += "\r\n"
|
60
|
+
native.classMethodVoid("%Net.Remote.Gateway", "%WriteOutput", formatted_value);
|
61
|
+
return
|
62
|
+
except BaseException as e:
|
63
|
+
self.hmap[thread_id] += str(value)
|
64
|
+
return
|
65
|
+
|