sqlalchemy-iris 0.10.6b1__tar.gz → 0.11.0__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.
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/PKG-INFO +2 -1
- sqlalchemy-iris-0.11.0/intersystems_iris/_IRISOREF.py +9 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_DBAPI.py +112 -18
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_IRISStream.py +2 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_Parameter.py +55 -23
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_ParameterCollection.py +9 -1
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/iris/__init__.py +7 -0
- sqlalchemy-iris-0.11.0/iris/iris_ipm.py +40 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/setup.cfg +1 -1
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/base.py +5 -2
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/PKG-INFO +2 -1
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/SOURCES.txt +1 -3
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/tests/test_suite.py +54 -0
- sqlalchemy-iris-0.10.6b1/intersystems_iris/_IRISOREF.py +0 -4
- sqlalchemy-iris-0.10.6b1/iris/iris_site.py +0 -13
- sqlalchemy-iris-0.10.6b1/iris/irisbuiltins.py +0 -97
- sqlalchemy-iris-0.10.6b1/iris/irisloader.py +0 -199
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/LICENSE +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/README.md +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_BufferReader.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_BufferWriter.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ConnectionInformation.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ConnectionParameters.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_Constant.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_DBList.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_Device.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_GatewayContext.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_GatewayException.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_GatewayUtility.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRIS.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISConnection.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISEmbedded.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISGlobalNode.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISGlobalNodeView.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISIterator.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISList.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISNative.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISObject.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISReference.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_InStream.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_LegacyIterator.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ListItem.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ListReader.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ListWriter.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_LogFileStream.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_MessageHeader.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_OutStream.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_PrintStream.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_PythonGateway.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_SharedMemorySocket.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/__init__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/__main__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_Column.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_Descriptor.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_Message.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_ResultSetRow.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_SQLType.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/__init__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_PreParser.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_Scanner.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_Token.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_TokenList.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/__init__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessHost.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessOperation.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessProcess.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessService.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_Common.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_Director.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISBusinessOperation.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISBusinessService.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISInboundAdapter.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISOutboundAdapter.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_InboundAdapter.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_Message.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_OutboundAdapter.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/__init__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/irisnative/_IRISNative.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/irisnative/__init__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/setup.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/__init__.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/alembic.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/embedded.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/information_schema.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/iris.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/provision.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/requirements.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris/types.py +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/dependency_links.txt +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/entry_points.txt +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/requires.txt +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/top_level.txt +0 -0
- {sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/tests/test_alembic.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sqlalchemy-iris
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.11.0
|
4
4
|
Summary: InterSystems IRIS for SQLAlchemy
|
5
5
|
Home-page: https://github.com/caretdev/sqlalchemy-iris
|
6
6
|
Maintainer: CaretDev
|
@@ -22,6 +22,7 @@ Classifier: Operating System :: OS Independent
|
|
22
22
|
Requires-Python: >=3.8
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
|
+
Requires-Dist: SQLAlchemy>=1.3
|
25
26
|
|
26
27
|
sqlalchemy-iris
|
27
28
|
===
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import struct
|
2
|
+
import copy
|
1
3
|
import enum
|
2
4
|
import copy
|
3
5
|
import decimal
|
@@ -17,6 +19,7 @@ from intersystems_iris.dbapi._IRISStream import (
|
|
17
19
|
IRISStream,
|
18
20
|
IRISBinaryStream,
|
19
21
|
)
|
22
|
+
from intersystems_iris._IRISOREF import _IRISOREF
|
20
23
|
from ._SQLType import SQLType
|
21
24
|
|
22
25
|
from .._IRISNative import connect as native_connect
|
@@ -308,7 +311,7 @@ class _BaseCursor:
|
|
308
311
|
seq_of_params = tuple(seq_of_params)
|
309
312
|
|
310
313
|
self.statement = operation
|
311
|
-
self.params = seq_of_params
|
314
|
+
self.params = copy.deepcopy(seq_of_params)
|
312
315
|
self._params.set_input_params(self.params)
|
313
316
|
|
314
317
|
self._cursor_type = CursorType.PREPARED
|
@@ -334,7 +337,7 @@ class _BaseCursor:
|
|
334
337
|
raise ValueError("INOUT/OUT parameters not permitted")
|
335
338
|
|
336
339
|
self._prepared_update_execute()
|
337
|
-
|
340
|
+
|
338
341
|
return self._rowcount
|
339
342
|
|
340
343
|
def _process_sqlcode(self, sqlcode, message=None):
|
@@ -646,13 +649,20 @@ class _BaseCursor:
|
|
646
649
|
|
647
650
|
def _update404(self):
|
648
651
|
with self._connection._lock:
|
652
|
+
# self._reset_cached_info()
|
649
653
|
self._validate_parameters()
|
654
|
+
# self._prepare()
|
655
|
+
# self._validate_prepared_parameters()
|
656
|
+
# self._prepared_update_execute()
|
650
657
|
self._send_direct_update_request()
|
651
658
|
|
652
659
|
# api properties and methods
|
653
660
|
@property
|
654
661
|
def description(self):
|
655
|
-
if self.
|
662
|
+
if self._statementType is StatementType.UPDATE:
|
663
|
+
return None
|
664
|
+
|
665
|
+
if self._columns is None:
|
656
666
|
return None
|
657
667
|
|
658
668
|
Column = namedtuple(
|
@@ -747,6 +757,12 @@ class Cursor(_BaseCursor):
|
|
747
757
|
return True
|
748
758
|
else:
|
749
759
|
return False
|
760
|
+
|
761
|
+
def _reset_cached_info(self):
|
762
|
+
if not self._connection._preparedCache or not hasattr(self._connection._preparedCache, "__iter__"):
|
763
|
+
return
|
764
|
+
if self._parsed_statement in self._connection._preparedCache:
|
765
|
+
del self._connection._preparedCache[self._parsed_statement]
|
750
766
|
|
751
767
|
def _prepare_cached(self, cached_statement):
|
752
768
|
self._statement_id = cached_statement.statement_id
|
@@ -1158,7 +1174,68 @@ class Cursor(_BaseCursor):
|
|
1158
1174
|
else:
|
1159
1175
|
self._rsrow = _ResultSetRow(self._connection, self._columns, 0)
|
1160
1176
|
|
1177
|
+
def _update_streams(self):
|
1178
|
+
sets = self._parameter_sets or 1
|
1179
|
+
self.params = list(self.params).copy()
|
1180
|
+
param_types = [param.type for param in self._params._params_list]
|
1181
|
+
|
1182
|
+
for i in range(sets):
|
1183
|
+
params = self._params.collect(i)
|
1184
|
+
for pi, param in enumerate(params):
|
1185
|
+
if param_types[pi] in (SQLType.LONGVARBINARY, SQLType.LONGVARCHAR) and param is not None:
|
1186
|
+
stream_oref = self._send_stream(param_types[pi], param)
|
1187
|
+
if isinstance(self.params[i], tuple):
|
1188
|
+
self.params[i] = list(self.params[i])
|
1189
|
+
if isinstance(self.params[i], list):
|
1190
|
+
self.params[i][pi] = stream_oref
|
1191
|
+
else:
|
1192
|
+
self.params[pi] = stream_oref
|
1193
|
+
|
1194
|
+
def _send_stream(self, param_type, value):
|
1195
|
+
if isinstance(value, _IRISOREF):
|
1196
|
+
return value
|
1197
|
+
if not isinstance(value, str) and not isinstance(value, bytes):
|
1198
|
+
raise Exception(f"Invalid value type for stream, got {type(value).__name__}, expected str or bytes")
|
1199
|
+
stream_oref = None
|
1200
|
+
offset = 0
|
1201
|
+
full_size = len(value)
|
1202
|
+
if full_size < 3 * 1024 * 1024:
|
1203
|
+
return value
|
1204
|
+
with self._connection._lock:
|
1205
|
+
while True:
|
1206
|
+
size = full_size
|
1207
|
+
if size == 0:
|
1208
|
+
break
|
1209
|
+
size = 4096 if size > 4096 else size
|
1210
|
+
chunk = value[offset:offset + size]
|
1211
|
+
if not isinstance(chunk, bytes):
|
1212
|
+
chunk = bytes(chunk, "utf-8")
|
1213
|
+
offset += size
|
1214
|
+
full_size -= size
|
1215
|
+
|
1216
|
+
# message header
|
1217
|
+
code = _Message.STORE_BINARY_STREAM if param_type == SQLType.LONGVARBINARY else _Message.STORE_CHARACTER_STREAM
|
1218
|
+
self._out_message.wire._write_header(code)
|
1219
|
+
intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
|
1220
|
+
self._out_message.wire.buffer, self._statement_id
|
1221
|
+
)
|
1222
|
+
# message body
|
1223
|
+
self._out_message.wire._set(stream_oref or "0")
|
1224
|
+
self._out_message.wire._set_raw_bytes(struct.pack("<i", size))
|
1225
|
+
self._out_message.wire._set_raw_bytes(chunk)
|
1226
|
+
|
1227
|
+
# send
|
1228
|
+
sequence_number = self._connection._get_new_sequence_number()
|
1229
|
+
self._out_message._send(sequence_number)
|
1230
|
+
|
1231
|
+
self._in_message._read_message_sql(sequence_number, self._statement_id, 0)
|
1232
|
+
stream_oref = self._sqlcode = self._in_message.wire._get()
|
1233
|
+
|
1234
|
+
return _IRISOREF(stream_oref)
|
1235
|
+
|
1161
1236
|
def _prepared_update_execute(self):
|
1237
|
+
self._update_streams()
|
1238
|
+
|
1162
1239
|
# send PU message
|
1163
1240
|
with self._connection._lock:
|
1164
1241
|
# message header
|
@@ -1776,23 +1853,26 @@ class Cursor(_BaseCursor):
|
|
1776
1853
|
if self._connection == None or self._connection.isClosed():
|
1777
1854
|
return None
|
1778
1855
|
|
1779
|
-
if self._statementType is not StatementType.UPDATE:
|
1856
|
+
if self._statementType is not StatementType.UPDATE or self._rowcount < 1:
|
1780
1857
|
return None
|
1781
1858
|
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
#
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1859
|
+
if self._rowcount > 1:
|
1860
|
+
with self._connection.cursor() as cursor:
|
1861
|
+
cursor.execute("SELECT LAST_IDENTITY()")
|
1862
|
+
self._lastrowid = cursor.fetchone()[0]
|
1863
|
+
return self._lastrowid
|
1864
|
+
|
1865
|
+
# In multiple rows inserted it returns the first inserted value, not the last one
|
1866
|
+
with self._connection._lock:
|
1867
|
+
self._out_message.wire._write_header(_Message.GET_AUTO_GENERATED_KEYS)
|
1868
|
+
sequence_number = self._connection._get_new_sequence_number()
|
1869
|
+
self._out_message._send(sequence_number)
|
1870
|
+
self._in_message._read_message_sql(sequence_number)
|
1871
|
+
self._sqlcode = self._in_message.wire.header._get_function_code()
|
1872
|
+
if self._sqlcode != 100:
|
1873
|
+
raise DatabaseError(self._get_error_info(self._sqlcode))
|
1874
|
+
self._get_column_info(self._in_message.wire)
|
1875
|
+
self._lastrowid = self._in_message.wire._get()
|
1796
1876
|
return self._lastrowid
|
1797
1877
|
|
1798
1878
|
def _cleanup(self):
|
@@ -2304,8 +2384,22 @@ class EmbdeddedCursor(_BaseCursor):
|
|
2304
2384
|
self._rowcount = 0
|
2305
2385
|
self._lastrowid = None
|
2306
2386
|
sets = self._parameter_sets or 1
|
2387
|
+
metadata = self._statement.Statement._Metadata.parameters
|
2388
|
+
param_types = [metadata.GetAt(i + 1).ODBCType for i in range(metadata.Size)]
|
2389
|
+
|
2390
|
+
stream_chunk_size = 32000
|
2391
|
+
|
2307
2392
|
for i in range(sets):
|
2308
2393
|
params = self._get_parameters(i)
|
2394
|
+
for ip, param in enumerate(params):
|
2395
|
+
if param_types[ip] in (SQLType.LONGVARBINARY, SQLType.LONGVARCHAR):
|
2396
|
+
stream_class = '%Stream.GlobalBinary' if param_types[ip] == SQLType.LONGVARBINARY else '%Stream.GlobalCharacter'
|
2397
|
+
stream = self._iris.cls(stream_class)._New()
|
2398
|
+
while param:
|
2399
|
+
stream.Write(param[:stream_chunk_size])
|
2400
|
+
param = param[stream_chunk_size:]
|
2401
|
+
params[ip] = stream
|
2402
|
+
|
2309
2403
|
sqlcode = 0
|
2310
2404
|
message = None
|
2311
2405
|
try:
|
@@ -3,6 +3,7 @@ from .._MessageHeader import _MessageHeader
|
|
3
3
|
from .._InStream import _InStream
|
4
4
|
from .._OutStream import _OutStream
|
5
5
|
|
6
|
+
|
6
7
|
class IRISStream:
|
7
8
|
_handle = None
|
8
9
|
_binary = False
|
@@ -59,5 +60,6 @@ class IRISStream:
|
|
59
60
|
|
60
61
|
return result
|
61
62
|
|
63
|
+
|
62
64
|
class IRISBinaryStream(IRISStream):
|
63
65
|
_binary = True
|
@@ -2,6 +2,8 @@ import datetime
|
|
2
2
|
import decimal
|
3
3
|
import enum
|
4
4
|
import intersystems_iris.dbapi._Descriptor
|
5
|
+
from intersystems_iris._IRISOREF import _IRISOREF
|
6
|
+
|
5
7
|
|
6
8
|
class ParameterMode(enum.IntEnum):
|
7
9
|
UNKNOWN = 0
|
@@ -13,8 +15,22 @@ class ParameterMode(enum.IntEnum):
|
|
13
15
|
DEFAULT_PARAMETER = 6
|
14
16
|
RETURN_VALUE = 7
|
15
17
|
|
18
|
+
|
16
19
|
class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
|
17
|
-
def __init__(
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
value=None,
|
23
|
+
mode=ParameterMode.UNKNOWN,
|
24
|
+
paramType="?",
|
25
|
+
name="",
|
26
|
+
execParam=False,
|
27
|
+
bound=False,
|
28
|
+
type=0,
|
29
|
+
precision=0,
|
30
|
+
scale=None,
|
31
|
+
nullable=0,
|
32
|
+
slotPosition=None,
|
33
|
+
):
|
18
34
|
if not isinstance(mode, ParameterMode):
|
19
35
|
raise TypeError("mode must be a ParameterMode")
|
20
36
|
paramType = str(paramType)
|
@@ -48,23 +64,35 @@ class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
|
|
48
64
|
|
49
65
|
def __repr__(self) -> str:
|
50
66
|
if self.mode not in [ParameterMode.UNKNOWN, ParameterMode.INPUT]:
|
51
|
-
return f
|
67
|
+
return f"<{self.mode.name}>{repr(self.value)}"
|
52
68
|
else:
|
53
|
-
return f
|
69
|
+
return f"<{self.mode.name}>"
|
54
70
|
|
55
|
-
def Clone(self):
|
56
|
-
clone = _Parameter(
|
71
|
+
def Clone(self, value=None):
|
72
|
+
clone = _Parameter(
|
73
|
+
value or self.value,
|
74
|
+
self.mode,
|
75
|
+
self.paramType,
|
76
|
+
self.name,
|
77
|
+
self.execParam,
|
78
|
+
self.bound,
|
79
|
+
self.type,
|
80
|
+
self.precision,
|
81
|
+
self.scale,
|
82
|
+
self.nullable,
|
83
|
+
self.slotPosition,
|
84
|
+
)
|
57
85
|
clone.cloneMe(self)
|
58
|
-
|
86
|
+
|
59
87
|
clone.parsermatched = self.parsermatched
|
60
88
|
clone.matchedParameterList = self.matchedParameterList
|
61
|
-
|
89
|
+
|
62
90
|
return clone
|
63
91
|
|
64
92
|
@property
|
65
93
|
def bound(self):
|
66
94
|
return self.__bound
|
67
|
-
|
95
|
+
|
68
96
|
@property
|
69
97
|
def paramType(self):
|
70
98
|
return self.__paramType
|
@@ -72,17 +100,18 @@ class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
|
|
72
100
|
@property
|
73
101
|
def value(self):
|
74
102
|
_set_switcher = {
|
75
|
-
type(None): lambda v
|
103
|
+
type(None): lambda v: None,
|
76
104
|
# str: lambda v : v or b'\x00',
|
77
|
-
datetime.time: lambda v
|
78
|
-
datetime.date: lambda v
|
79
|
-
datetime.datetime: lambda v
|
80
|
-
bytes: lambda v
|
81
|
-
bytearray: lambda v
|
82
|
-
bool: lambda v
|
83
|
-
int: lambda v
|
84
|
-
float: lambda v
|
85
|
-
decimal.Decimal: lambda v
|
105
|
+
datetime.time: lambda v: v.strftime("%H:%M:%S.%f"),
|
106
|
+
datetime.date: lambda v: v.strftime("%Y-%m-%d"),
|
107
|
+
datetime.datetime: lambda v: v.strftime("%Y-%m-%d %H:%M:%S.%f"),
|
108
|
+
bytes: lambda v: v,
|
109
|
+
bytearray: lambda v: v,
|
110
|
+
bool: lambda v: 1 if v else 0,
|
111
|
+
int: lambda v: v,
|
112
|
+
float: lambda v: v,
|
113
|
+
decimal.Decimal: lambda v: v,
|
114
|
+
_IRISOREF: lambda v: str(v),
|
86
115
|
}
|
87
116
|
func = None
|
88
117
|
if issubclass(type(self.__value), enum.Enum):
|
@@ -103,9 +132,11 @@ class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
|
|
103
132
|
self.scale = desc.scale
|
104
133
|
self.nullable = desc.nullable
|
105
134
|
self.name = desc.name
|
106
|
-
if (
|
107
|
-
|
108
|
-
and (desc.mode != ParameterMode.
|
135
|
+
if (
|
136
|
+
(self.mode != ParameterMode.REPLACED_LITERAL)
|
137
|
+
and (desc.mode != ParameterMode.REPLACED_LITERAL)
|
138
|
+
and (desc.mode != ParameterMode.UNKNOWN)
|
139
|
+
):
|
109
140
|
self.mode = desc.mode
|
110
141
|
|
111
142
|
if not copy_replaced:
|
@@ -115,7 +146,8 @@ class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
|
|
115
146
|
self.mode = ParameterMode.REPLACED_LITERAL
|
116
147
|
self.__value = desc.value
|
117
148
|
self._values = list()
|
118
|
-
if len(desc._values) > 0:
|
149
|
+
if len(desc._values) > 0:
|
150
|
+
self._values.append(desc._values[0])
|
119
151
|
return
|
120
152
|
|
121
153
|
def _bind(self, value, parameter_sets):
|
@@ -136,4 +168,4 @@ class _Parameter(intersystems_iris.dbapi._Descriptor._Descriptor):
|
|
136
168
|
if self.mode == ParameterMode.OUTPUT or self.mode == ParameterMode.INPUT_OUTPUT:
|
137
169
|
self.mode = ParameterMode.INPUT_OUTPUT
|
138
170
|
else:
|
139
|
-
self.mode = ParameterMode.INPUT
|
171
|
+
self.mode = ParameterMode.INPUT
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_ParameterCollection.py
RENAMED
@@ -34,7 +34,7 @@ class _ParameterCollection:
|
|
34
34
|
self._array_bound = False
|
35
35
|
|
36
36
|
def set_input_params(self, params):
|
37
|
-
self._input_params = params
|
37
|
+
self._input_params = list(params)
|
38
38
|
|
39
39
|
def collect(self, i: int = 0) -> list:
|
40
40
|
params = list()
|
@@ -61,6 +61,14 @@ class _ParameterCollection:
|
|
61
61
|
|
62
62
|
return params
|
63
63
|
|
64
|
+
def update(self, set_index, param_index, value):
|
65
|
+
if isinstance(self._input_params[set_index], tuple):
|
66
|
+
self._input_params[set_index] = list(self._input_params[set_index])
|
67
|
+
if isinstance(self._input_params[set_index], list):
|
68
|
+
self._input_params[set_index][param_index] = value
|
69
|
+
else:
|
70
|
+
self._input_params[param_index] = value
|
71
|
+
|
64
72
|
def __repr__(self) -> str:
|
65
73
|
return repr(self.collect())
|
66
74
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from sys import path as __syspath
|
2
2
|
import os
|
3
|
+
from .iris_ipm import ipm
|
3
4
|
|
4
5
|
# check for install dir in environment
|
5
6
|
# environment to check is IRISINSTALLDIR
|
@@ -15,8 +16,14 @@ __syspath.append(os.path.join(installdir, 'bin'))
|
|
15
16
|
# also append lib/python
|
16
17
|
__syspath.append(os.path.join(installdir, 'lib', 'python'))
|
17
18
|
|
19
|
+
# save working directory
|
20
|
+
__ospath = os.getcwd()
|
21
|
+
|
18
22
|
from pythonint import *
|
19
23
|
|
24
|
+
# restore working directory
|
25
|
+
os.chdir(__ospath)
|
26
|
+
|
20
27
|
# TODO: Figure out how to hide __syspath and __ospath from anyone that
|
21
28
|
# imports iris. Tried __all__ but that only applies to this:
|
22
29
|
# from iris import *
|
@@ -0,0 +1,40 @@
|
|
1
|
+
def ipm(cmd, *args):
|
2
|
+
"""
|
3
|
+
Executes shell command with IPM:
|
4
|
+
Parameters
|
5
|
+
----------
|
6
|
+
cmd : str
|
7
|
+
The command to execute
|
8
|
+
Examples
|
9
|
+
--------
|
10
|
+
`ipm('help')`
|
11
|
+
`ipm('load /home/irisowner/dev -v')`
|
12
|
+
`ipm('install webterminal')`
|
13
|
+
"""
|
14
|
+
|
15
|
+
import multiprocessing
|
16
|
+
import iris
|
17
|
+
|
18
|
+
def shell(cmd, status):
|
19
|
+
|
20
|
+
|
21
|
+
status.put(True)
|
22
|
+
|
23
|
+
res = iris.cls("%ZPM.PackageManager").Shell(cmd)
|
24
|
+
print('')
|
25
|
+
if res != 1:
|
26
|
+
status.get()
|
27
|
+
status.put(False)
|
28
|
+
|
29
|
+
manager = multiprocessing.Manager()
|
30
|
+
status = manager.Queue()
|
31
|
+
process = multiprocessing.Process(
|
32
|
+
target=shell,
|
33
|
+
args=(
|
34
|
+
cmd,
|
35
|
+
status,
|
36
|
+
),
|
37
|
+
)
|
38
|
+
process.start()
|
39
|
+
process.join()
|
40
|
+
return status.get()
|
@@ -745,6 +745,9 @@ class IRISTypeCompiler(compiler.GenericTypeCompiler):
|
|
745
745
|
def visit_DOUBLE(self, type_, **kw):
|
746
746
|
return "DOUBLE"
|
747
747
|
|
748
|
+
def visit_TINYINT(self, type_, **kw):
|
749
|
+
return "TINYINT"
|
750
|
+
|
748
751
|
|
749
752
|
class IRISIdentifierPreparer(sql.compiler.IdentifierPreparer):
|
750
753
|
"""Install IRIS specific reserved words."""
|
@@ -1486,7 +1489,7 @@ There are no access to %Dictionary, may be required for some advanced features,
|
|
1486
1489
|
|
1487
1490
|
if fkdelrule != "NO ACTION":
|
1488
1491
|
fkey["options"]["ondelete"] = fkdelrule
|
1489
|
-
|
1492
|
+
|
1490
1493
|
if scol not in fkey["constrained_columns"]:
|
1491
1494
|
fkey["constrained_columns"].append(scol)
|
1492
1495
|
if rcol not in fkey["referred_columns"]:
|
@@ -1686,7 +1689,7 @@ There are no access to %Dictionary, may be required for some advanced features,
|
|
1686
1689
|
if view_def:
|
1687
1690
|
return view_def
|
1688
1691
|
raise exc.NoSuchTableError(f"{schema}.{view_name}")
|
1689
|
-
|
1692
|
+
|
1690
1693
|
def normalize_name(self, name):
|
1691
1694
|
if self.identifier_preparer._requires_quotes(name):
|
1692
1695
|
return quoted_name(name, quote=True)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sqlalchemy-iris
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.11.0
|
4
4
|
Summary: InterSystems IRIS for SQLAlchemy
|
5
5
|
Home-page: https://github.com/caretdev/sqlalchemy-iris
|
6
6
|
Maintainer: CaretDev
|
@@ -22,6 +22,7 @@ Classifier: Operating System :: OS Independent
|
|
22
22
|
Requires-Python: >=3.8
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
|
+
Requires-Dist: SQLAlchemy>=1.3
|
25
26
|
|
26
27
|
sqlalchemy-iris
|
27
28
|
===
|
@@ -66,9 +66,7 @@ intersystems_iris/pex/_Message.py
|
|
66
66
|
intersystems_iris/pex/_OutboundAdapter.py
|
67
67
|
intersystems_iris/pex/__init__.py
|
68
68
|
iris/__init__.py
|
69
|
-
iris/
|
70
|
-
iris/irisbuiltins.py
|
71
|
-
iris/irisloader.py
|
69
|
+
iris/iris_ipm.py
|
72
70
|
irisnative/_IRISNative.py
|
73
71
|
irisnative/__init__.py
|
74
72
|
sqlalchemy_iris/__init__.py
|
@@ -4,6 +4,9 @@ from sqlalchemy.testing.suite import FetchLimitOffsetTest as _FetchLimitOffsetTe
|
|
4
4
|
from sqlalchemy.testing.suite import CompoundSelectTest as _CompoundSelectTest
|
5
5
|
from sqlalchemy.testing.suite import CTETest as _CTETest
|
6
6
|
from sqlalchemy.testing.suite import DifficultParametersTest as _DifficultParametersTest
|
7
|
+
from sqlalchemy.testing.suite import (
|
8
|
+
BizarroCharacterFKResolutionTest as _BizarroCharacterFKResolutionTest,
|
9
|
+
)
|
7
10
|
from sqlalchemy.testing import fixtures
|
8
11
|
from sqlalchemy.testing.assertions import eq_
|
9
12
|
from sqlalchemy.testing import config
|
@@ -14,6 +17,8 @@ from sqlalchemy.types import Integer
|
|
14
17
|
from sqlalchemy.types import String
|
15
18
|
from sqlalchemy.types import VARBINARY
|
16
19
|
from sqlalchemy.types import BINARY
|
20
|
+
from sqlalchemy_iris import TINYINT
|
21
|
+
from sqlalchemy.exc import DatabaseError
|
17
22
|
import pytest
|
18
23
|
|
19
24
|
from sqlalchemy.testing.suite import * # noqa
|
@@ -71,6 +76,39 @@ class FetchLimitOffsetTest(_FetchLimitOffsetTest):
|
|
71
76
|
)
|
72
77
|
|
73
78
|
|
79
|
+
class TinyintTest(fixtures.TablesTest):
|
80
|
+
__backend__ = True
|
81
|
+
|
82
|
+
@classmethod
|
83
|
+
def define_tables(cls, metadata):
|
84
|
+
Table(
|
85
|
+
"test_tinyint",
|
86
|
+
metadata,
|
87
|
+
Column("val_tinyint", TINYINT),
|
88
|
+
)
|
89
|
+
|
90
|
+
@testing.fixture
|
91
|
+
def local_connection(self):
|
92
|
+
with testing.db.connect() as conn:
|
93
|
+
yield conn
|
94
|
+
|
95
|
+
def test_commits(self, local_connection):
|
96
|
+
test_tinyint = self.tables.test_tinyint
|
97
|
+
connection = local_connection
|
98
|
+
|
99
|
+
transaction = connection.begin()
|
100
|
+
connection.execute(test_tinyint.insert(), dict(val_tinyint=100))
|
101
|
+
with pytest.raises(DatabaseError):
|
102
|
+
connection.execute(test_tinyint.insert(), dict(val_tinyint=129))
|
103
|
+
with pytest.raises(DatabaseError):
|
104
|
+
connection.execute(test_tinyint.insert(), dict(val_tinyint=-129))
|
105
|
+
transaction.commit()
|
106
|
+
|
107
|
+
result = connection.exec_driver_sql("select * from test_tinyint")
|
108
|
+
assert len(result.fetchall()) == 1
|
109
|
+
connection.close()
|
110
|
+
|
111
|
+
|
74
112
|
class TransactionTest(fixtures.TablesTest):
|
75
113
|
__backend__ = True
|
76
114
|
|
@@ -227,3 +265,19 @@ class IRISEnumTest(fixtures.TablesTest):
|
|
227
265
|
select(self.tables.data),
|
228
266
|
[(SomeType.FIRST,), (SomeType.SECOND,), (None,)],
|
229
267
|
)
|
268
|
+
|
269
|
+
|
270
|
+
class BizarroCharacterFKResolutionTest(_BizarroCharacterFKResolutionTest):
|
271
|
+
@testing.combinations(
|
272
|
+
("id",), ("(3)",), ("col%p",), ("[brack]",), argnames="columnname"
|
273
|
+
)
|
274
|
+
@testing.variation("use_composite", [True, False])
|
275
|
+
@testing.combinations(
|
276
|
+
("plain",),
|
277
|
+
# ("(2)",), not in IRIS
|
278
|
+
("per % cent",),
|
279
|
+
("[brackets]",),
|
280
|
+
argnames="tablename",
|
281
|
+
)
|
282
|
+
def test_fk_ref(self, connection, metadata, use_composite, tablename, columnname):
|
283
|
+
super().test_fk_ref(connection, metadata, use_composite, tablename, columnname)
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
from os import sep as __os_sep
|
3
|
-
from site import getsitepackages as __sitegetsitepackages
|
4
|
-
|
5
|
-
#ubuntu needs dist-packages for pandas to be able to be imported
|
6
|
-
#ubu 18 doesnt have os.sep in sys.executable
|
7
|
-
def set_site_path(platform_name):
|
8
|
-
if "ubuntu" in platform_name:
|
9
|
-
if __os_sep in sys.executable:
|
10
|
-
__siteprefixes = [__os_sep + sys.executable.split(__os_sep)[1]]
|
11
|
-
else:
|
12
|
-
__siteprefixes = ['/usr']
|
13
|
-
sys.path = sys.path + __sitegetsitepackages(__siteprefixes)
|
@@ -1,97 +0,0 @@
|
|
1
|
-
from collections import abc
|
2
|
-
|
3
|
-
#
|
4
|
-
# IRIS Exceptions
|
5
|
-
#
|
6
|
-
class SQLError(Exception):
|
7
|
-
"""Error raised on an invalid IRIS SQL statement
|
8
|
-
|
9
|
-
Attributes:
|
10
|
-
sqlcode -- IRIS SQL error code
|
11
|
-
message -- Error description
|
12
|
-
statement -- Statement that failed
|
13
|
-
"""
|
14
|
-
|
15
|
-
def __init__(self,sqlcode,message,statement=None):
|
16
|
-
self.sqlcode = sqlcode
|
17
|
-
self.message = message
|
18
|
-
self.statement = statement
|
19
|
-
super().__init__(self.message)
|
20
|
-
|
21
|
-
#
|
22
|
-
# Helper to raise a properly formatted AttributeError when we decide that
|
23
|
-
# we don't want to handle a last-chance method.
|
24
|
-
#
|
25
|
-
def _no_such_method(target,method):
|
26
|
-
raise AttributeError(f"'{target.__class__.__name__}' has no attribute '{method}'")
|
27
|
-
|
28
|
-
#
|
29
|
-
# irisbuiltins: Implements impedence matching methods for projecting IRIS behavior
|
30
|
-
# over Python objects.
|
31
|
-
#
|
32
|
-
class irisbuiltins:
|
33
|
-
|
34
|
-
#
|
35
|
-
# Common functions for mapping Python collection behavior to IRIS behavior
|
36
|
-
#
|
37
|
-
# NOTE: With Sequences, the indicies are 0 based for Python and 1 based
|
38
|
-
# for IRIS.
|
39
|
-
#
|
40
|
-
|
41
|
-
def Count(self):
|
42
|
-
if isinstance(self,abc.Mapping) or isinstance(self,abc.Sequence):
|
43
|
-
return len(self)
|
44
|
-
_no_such_method(self,"Count")
|
45
|
-
|
46
|
-
def GetAt(self,index):
|
47
|
-
if isinstance(self,abc.Mapping):
|
48
|
-
return self[index]
|
49
|
-
if isinstance(self,abc.Sequence):
|
50
|
-
return self[index-1]
|
51
|
-
_no_such_method(self,"GetAt")
|
52
|
-
|
53
|
-
def SetAt(self,value,index):
|
54
|
-
if isinstance(self,abc.Mapping):
|
55
|
-
self[index] = value
|
56
|
-
return
|
57
|
-
if isinstance(self,abc.Sequence):
|
58
|
-
self[index-1] = value
|
59
|
-
return
|
60
|
-
_no_such_method(self,"SetAt")
|
61
|
-
|
62
|
-
def Insert(self,value):
|
63
|
-
if isinstance(self,abc.Sequence):
|
64
|
-
self.append(value)
|
65
|
-
return
|
66
|
-
_no_such_method(self,"Insert")
|
67
|
-
|
68
|
-
def InsertAt(self,value,index):
|
69
|
-
if isinstance(self,abc.Sequence):
|
70
|
-
self.insert(index-1,value)
|
71
|
-
return
|
72
|
-
_no_such_method(self,"InsertAt")
|
73
|
-
|
74
|
-
def Clear(self):
|
75
|
-
if isinstance(self,abc.Mapping) or isinstance(self,abc.Sequence):
|
76
|
-
self.clear()
|
77
|
-
return
|
78
|
-
_no_such_method(self,"Clear")
|
79
|
-
|
80
|
-
def IsDefined(self,key):
|
81
|
-
if isinstance(self,abc.Mapping):
|
82
|
-
return (key in self)
|
83
|
-
_no_such_method(self,"IsDefined")
|
84
|
-
|
85
|
-
def Find(self,value):
|
86
|
-
if isinstance(self,abc.Sequence):
|
87
|
-
return self.index(value)+1
|
88
|
-
if isinstance(self,abc.Mapping):
|
89
|
-
for (k,v) in self.items():
|
90
|
-
if v == value:
|
91
|
-
return k
|
92
|
-
return None;
|
93
|
-
_no_such_method(self,"Find")
|
94
|
-
|
95
|
-
#
|
96
|
-
# End-of-file
|
97
|
-
#
|
@@ -1,199 +0,0 @@
|
|
1
|
-
from importlib.abc import MetaPathFinder
|
2
|
-
from importlib.abc import Loader
|
3
|
-
import importlib
|
4
|
-
from types import ModuleType
|
5
|
-
import math
|
6
|
-
import marshal
|
7
|
-
import sys
|
8
|
-
import iris
|
9
|
-
|
10
|
-
sources=iris.gref("^ROUTINE")
|
11
|
-
binaries=iris.gref("^rPYC")
|
12
|
-
MAX_STRING_SIZE=3800000
|
13
|
-
|
14
|
-
def getFromDirectory(directory, path):
|
15
|
-
level=len(path)
|
16
|
-
if level == 1:
|
17
|
-
return directory[path[0]]
|
18
|
-
elif level == 2:
|
19
|
-
return directory[path[0],path[1]]
|
20
|
-
elif level == 3:
|
21
|
-
return directory[path[0],path[1],path[2]]
|
22
|
-
elif level == 4:
|
23
|
-
return directory[path[0],path[1],path[2],path[3]]
|
24
|
-
elif level == 5:
|
25
|
-
return directory[path[0],path[1],path[2],path[3],path[4]]
|
26
|
-
elif level == 6:
|
27
|
-
return directory[path[0],path[1],path[2],path[3],path[4],path[5]]
|
28
|
-
elif level == 7:
|
29
|
-
return directory[path[0],path[1],path[2],path[3],path[4],path[5],path[6]]
|
30
|
-
elif level == 8:
|
31
|
-
return directory[path[0],path[1],path[2],path[3],path[4],path[5],path[6],path[7]]
|
32
|
-
elif level == 9:
|
33
|
-
return directory[path[0],path[1],path[2],path[3],path[4],path[5],path[6],path[7],path[8]]
|
34
|
-
|
35
|
-
#name is name of rtn with .py
|
36
|
-
def getSourceCode(name):
|
37
|
-
currentP = [name] + [0,0]
|
38
|
-
length = getFromDirectory(sources, currentP)
|
39
|
-
currentP.pop()
|
40
|
-
if not length or length == 0:
|
41
|
-
return None
|
42
|
-
code = ""
|
43
|
-
for i in range(1,int(length)+1):
|
44
|
-
currentP.append(i)
|
45
|
-
code += getFromDirectory(sources, currentP)
|
46
|
-
code += "\r\n"
|
47
|
-
currentP.pop()
|
48
|
-
return code
|
49
|
-
|
50
|
-
def getCodeFromBinary(name):
|
51
|
-
length = binaries.get([name],0)
|
52
|
-
if (length < 1):
|
53
|
-
return None
|
54
|
-
codeBytes = binaries.getAsBytes([name,1])
|
55
|
-
for i in range(1,int(length)):
|
56
|
-
codeBytes += binaries.getAsBytes([name,i+1])
|
57
|
-
return marshal.loads(codeBytes)
|
58
|
-
|
59
|
-
# def checkCode(directory, path):
|
60
|
-
# currentP = [p for p in path] + [0,0]
|
61
|
-
# length = getFromDirectory(directory, currentP)
|
62
|
-
# currentP.pop()
|
63
|
-
# if not length or length == 0:
|
64
|
-
# return None
|
65
|
-
# return length
|
66
|
-
|
67
|
-
def checkCode(name):
|
68
|
-
#code exist for module
|
69
|
-
|
70
|
-
if binaries.get([name],0) > 0:
|
71
|
-
return True
|
72
|
-
sub = binaries.order([name+"."])
|
73
|
-
#there exists some subpackage
|
74
|
-
if (sub and sub[:len(name)] == name):
|
75
|
-
return True
|
76
|
-
return False
|
77
|
-
|
78
|
-
def compileCode(name):
|
79
|
-
path = name.split(".")
|
80
|
-
classname = path[-1]
|
81
|
-
code = getSourceCode(name+".py")
|
82
|
-
if code:
|
83
|
-
codeobj = compile(code,classname,"exec")
|
84
|
-
compiledpython = marshal.dumps(codeobj)
|
85
|
-
|
86
|
-
#store in database
|
87
|
-
length=len(compiledpython)
|
88
|
-
chunks = math.ceil(length / MAX_STRING_SIZE)
|
89
|
-
binaries[name] = chunks
|
90
|
-
for i in range(chunks):
|
91
|
-
binaries[name,i+1] = compiledpython[i*MAX_STRING_SIZE:min(MAX_STRING_SIZE*(i+1),length)]
|
92
|
-
|
93
|
-
#delete old version of this module
|
94
|
-
# if name in sys.modules:
|
95
|
-
# del sys.modules[name]
|
96
|
-
return 1
|
97
|
-
return 0
|
98
|
-
|
99
|
-
#
|
100
|
-
# Impedence matcher prototype
|
101
|
-
#
|
102
|
-
|
103
|
-
def mapping_GetAt(self,key):
|
104
|
-
return self[key]
|
105
|
-
|
106
|
-
def mapping_SetAt(self,value,key):
|
107
|
-
self[key] = value
|
108
|
-
|
109
|
-
def sequence_GetAt(self,index):
|
110
|
-
return self[index-1]
|
111
|
-
|
112
|
-
def sequence_SetAt(self,value,index):
|
113
|
-
self[index-1] = value
|
114
|
-
|
115
|
-
def materialize(obj):
|
116
|
-
if isinstance(obj,collections.abc.Mapping):
|
117
|
-
obj.Count = obj.__len__
|
118
|
-
obj.GetAt = mapping_GetAt
|
119
|
-
obj.SetAt = mapping_SetAt
|
120
|
-
return True
|
121
|
-
if isinstance(obj,collections.abc.Sequence):
|
122
|
-
obj.Count = obj.__len__
|
123
|
-
obj.GetAt = sequence_GetAt
|
124
|
-
obj.SetAt = sequence_SetAt
|
125
|
-
return True
|
126
|
-
return False
|
127
|
-
|
128
|
-
class MyLoader(Loader):
|
129
|
-
def create_module(self,spec):
|
130
|
-
|
131
|
-
module = ModuleType(spec.name)
|
132
|
-
module.__spec__=spec
|
133
|
-
module.__loader__ = self
|
134
|
-
module.__path__ = spec.__path__
|
135
|
-
return module
|
136
|
-
|
137
|
-
def exec_module(self, module):
|
138
|
-
#path = [p+".py" for p in module.__path__]
|
139
|
-
name = ""
|
140
|
-
code = None
|
141
|
-
for n in module.__path__:
|
142
|
-
name += n
|
143
|
-
name += "."
|
144
|
-
if name:
|
145
|
-
code = getCodeFromBinary(name[:len(name)-1])
|
146
|
-
|
147
|
-
#this is a class or has code by itself
|
148
|
-
if code:
|
149
|
-
#print(marshal.loads(bytes(code,"utf-8")))
|
150
|
-
#print(type(code))
|
151
|
-
exec(code,module.__dict__)
|
152
|
-
#this is a module
|
153
|
-
# ismodule = getFromDirectory(path+["catalog"])
|
154
|
-
# if ismodule:
|
155
|
-
# for s in ismodule.split(","):
|
156
|
-
# code = getFromDirectory(path+[s])
|
157
|
-
# if code:
|
158
|
-
# exec(code,module.__dict__)
|
159
|
-
|
160
|
-
|
161
|
-
class MyFinder(MetaPathFinder):
|
162
|
-
def __init__(self):
|
163
|
-
return
|
164
|
-
|
165
|
-
def find_spec(self,fullname,path,target=None):
|
166
|
-
|
167
|
-
#print("importing1: "+fullname)
|
168
|
-
ans = fullname.split(".")
|
169
|
-
currentName=ans[-1]
|
170
|
-
for i in range(len(ans)):
|
171
|
-
ans[i] += ".py"
|
172
|
-
#validate existance from globals
|
173
|
-
#this might be wrong
|
174
|
-
if not checkCode(fullname):
|
175
|
-
return None
|
176
|
-
spec = importlib.machinery.ModuleSpec(fullname, MyLoader())
|
177
|
-
#update path
|
178
|
-
if path:
|
179
|
-
spec.__path__ = path + [currentName]
|
180
|
-
else:
|
181
|
-
spec.__path__ = [currentName]
|
182
|
-
# set parent
|
183
|
-
if len(ans) == 1:
|
184
|
-
if path:
|
185
|
-
spec.__parent__=path[-1]
|
186
|
-
else:
|
187
|
-
spec.__parent__= None
|
188
|
-
else:
|
189
|
-
spec.__parent__=ans[-1]
|
190
|
-
|
191
|
-
return spec
|
192
|
-
|
193
|
-
|
194
|
-
sys.meta_path.append(MyFinder())
|
195
|
-
#del sys
|
196
|
-
#test:
|
197
|
-
#s imp = ##class(%SYS.Python).Import("customImport")
|
198
|
-
#s xx = ##class(%SYS.Python).Import("User")
|
199
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ConnectionInformation.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_ConnectionParameters.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_IRISGlobalNodeView.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/_SharedMemorySocket.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/_ResultSetRow.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_PreParser.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_Scanner.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_Token.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/_TokenList.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/dbapi/preparser/__init__.py
RENAMED
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessOperation.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessProcess.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_BusinessService.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISBusinessOperation.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISBusinessService.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISInboundAdapter.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_IRISOutboundAdapter.py
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_InboundAdapter.py
RENAMED
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/intersystems_iris/pex/_OutboundAdapter.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/dependency_links.txt
RENAMED
File without changes
|
{sqlalchemy-iris-0.10.6b1 → sqlalchemy-iris-0.11.0}/sqlalchemy_iris.egg-info/entry_points.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|