e6data-python-connector 1.0.0__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.
- e6data_python_connector-1.0.0.dist-info/LICENSE +202 -0
- e6data_python_connector-1.0.0.dist-info/METADATA +205 -0
- e6data_python_connector-1.0.0.dist-info/RECORD +19 -0
- e6data_python_connector-1.0.0.dist-info/WHEEL +5 -0
- e6data_python_connector-1.0.0.dist-info/entry_points.txt +2 -0
- e6data_python_connector-1.0.0.dist-info/top_level.txt +1 -0
- e6xdb/__init__.py +10 -0
- e6xdb/common.py +269 -0
- e6xdb/constants.py +32 -0
- e6xdb/datainputstream.py +170 -0
- e6xdb/date_time_utils.py +167 -0
- e6xdb/e6x.py +467 -0
- e6xdb/exceptions.py +15 -0
- e6xdb/server/QueryEngineService.py +3776 -0
- e6xdb/server/__init__.py +1 -0
- e6xdb/server/constants.py +14 -0
- e6xdb/server/ttypes.py +342 -0
- e6xdb/sqlalchemy_e6x.py +396 -0
- e6xdb/typeId.py +73 -0
e6xdb/common.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""Package private common utilities. Do not use directly.
|
|
2
|
+
Many docstrings in this file are based on PEP-249, which is in the public domain.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import absolute_import
|
|
6
|
+
from __future__ import unicode_literals
|
|
7
|
+
|
|
8
|
+
import abc
|
|
9
|
+
import collections
|
|
10
|
+
import datetime
|
|
11
|
+
import logging
|
|
12
|
+
import time
|
|
13
|
+
from builtins import bytes
|
|
14
|
+
from builtins import int
|
|
15
|
+
from builtins import object
|
|
16
|
+
from builtins import str
|
|
17
|
+
|
|
18
|
+
from future.utils import with_metaclass
|
|
19
|
+
from past.builtins import basestring
|
|
20
|
+
|
|
21
|
+
from e6xdb.exceptions import ProgrammingError
|
|
22
|
+
|
|
23
|
+
_logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class DBAPICursor(with_metaclass(abc.ABCMeta, object)):
|
|
27
|
+
"""Base class for some common DB-API logic"""
|
|
28
|
+
|
|
29
|
+
_STATE_NONE = 0
|
|
30
|
+
_STATE_RUNNING = 1
|
|
31
|
+
_STATE_FINISHED = 2
|
|
32
|
+
|
|
33
|
+
def __init__(self, poll_interval=1):
|
|
34
|
+
self._poll_interval = poll_interval
|
|
35
|
+
self._reset_state()
|
|
36
|
+
self.lastrowid = None
|
|
37
|
+
self._data = None
|
|
38
|
+
|
|
39
|
+
def _reset_state(self):
|
|
40
|
+
"""Reset state about the previous query in preparation for running another query"""
|
|
41
|
+
# State to return as part of DB-API
|
|
42
|
+
self._rownumber = 0
|
|
43
|
+
|
|
44
|
+
# Internal helper state
|
|
45
|
+
self._data = collections.deque()
|
|
46
|
+
self._columns = None
|
|
47
|
+
|
|
48
|
+
def _fetch_while(self, fn):
|
|
49
|
+
_logger.info("Commons - fetch while.... fn type - {}".format(type(fn)))
|
|
50
|
+
while fn():
|
|
51
|
+
_logger.info("fetching next fetch more from fetch while")
|
|
52
|
+
self._fetch_more()
|
|
53
|
+
if fn():
|
|
54
|
+
time.sleep(self._poll_interval)
|
|
55
|
+
|
|
56
|
+
@abc.abstractmethod
|
|
57
|
+
def description(self):
|
|
58
|
+
raise NotImplementedError # pragma: no cover
|
|
59
|
+
|
|
60
|
+
def close(self):
|
|
61
|
+
"""By default, do nothing"""
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
@abc.abstractmethod
|
|
65
|
+
def _fetch_more(self):
|
|
66
|
+
"""Get more results, append it to ``self._data``, and update ``self._state``."""
|
|
67
|
+
raise NotImplementedError # pragma: no cover
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def rowcount(self):
|
|
71
|
+
"""By default, return -1 to indicate that this is not supported."""
|
|
72
|
+
return self.rowcount
|
|
73
|
+
|
|
74
|
+
@abc.abstractmethod
|
|
75
|
+
def execute(self, operation, parameters=None):
|
|
76
|
+
"""Prepare and execute a database operation (query or command).
|
|
77
|
+
Parameters may be provided as sequence or mapping and will be bound to variables in the
|
|
78
|
+
operation. Variables are specified in a database-specific notation (see the e6xdb's
|
|
79
|
+
``paramstyle`` attribute for details).
|
|
80
|
+
Return values are not defined.
|
|
81
|
+
"""
|
|
82
|
+
raise NotImplementedError # pragma: no cover
|
|
83
|
+
|
|
84
|
+
def executemany(self, operation, seq_of_parameters):
|
|
85
|
+
"""Prepare a database operation (query or command) and then execute it against all parameter
|
|
86
|
+
sequences or mappings found in the sequence ``seq_of_parameters``.
|
|
87
|
+
Only the final result set is retained.
|
|
88
|
+
Return values are not defined.
|
|
89
|
+
"""
|
|
90
|
+
for parameters in seq_of_parameters[:-1]:
|
|
91
|
+
self.execute(operation, parameters)
|
|
92
|
+
# while self._state != self._STATE_FINISHED:
|
|
93
|
+
# self._fetch_more()
|
|
94
|
+
if seq_of_parameters:
|
|
95
|
+
self.execute(operation, seq_of_parameters[-1])
|
|
96
|
+
|
|
97
|
+
def fetchone(self):
|
|
98
|
+
"""Fetch the next row of a query result set, returning a single sequence, or ``None`` when
|
|
99
|
+
no more data is available.
|
|
100
|
+
An :py:class:`~pyhive.exc.Error` (or subclass) exception is raised if the previous call to
|
|
101
|
+
:py:meth:`execute` did not produce any result set or no call was issued yet.
|
|
102
|
+
"""
|
|
103
|
+
# if self._state == self._STATE_NONE:
|
|
104
|
+
# raise ProgrammingError("No query yet")
|
|
105
|
+
#
|
|
106
|
+
# # Sleep until we're done or we have some data to return
|
|
107
|
+
# self._fetch_while(lambda: not self._data and self._state != self._STATE_FINISHED)
|
|
108
|
+
|
|
109
|
+
# Sleep until we're done or we have some data to return
|
|
110
|
+
# self._fetch_while(lambda: not self._data and self._state != self._STATE_FINISHED)
|
|
111
|
+
if not self._data:
|
|
112
|
+
return None
|
|
113
|
+
else:
|
|
114
|
+
# if self._rownumber <= 1000:
|
|
115
|
+
# _logger.info("Commons - Breaking the loop after 1000Commons - fetch many records")
|
|
116
|
+
# return None
|
|
117
|
+
self._rownumber += 1
|
|
118
|
+
return self._data.popleft()
|
|
119
|
+
|
|
120
|
+
def fetchmany(self, size=None):
|
|
121
|
+
"""Fetch the next set of rows of a query result, returning a sequence of sequences (e.g. a
|
|
122
|
+
list of tuples). An empty sequence is returned when no more rows are available.
|
|
123
|
+
The number of rows to fetch per call is specified by the parameter. If it is not given, the
|
|
124
|
+
cursor's arraysize determines the number of rows to be fetched. The method should try to
|
|
125
|
+
fetch as many rows as indicated by the size parameter. If this is not possible due to the
|
|
126
|
+
specified number of rows not being available, fewer rows may be returned.
|
|
127
|
+
An :py:class:`~pyhive.exc.Error` (or subclass) exception is raised if the previous call to
|
|
128
|
+
:py:meth:`execute` did not produce any result set or no call was issued yet.
|
|
129
|
+
"""
|
|
130
|
+
_logger.info("Commons - fetch many.... size - {}".format(size))
|
|
131
|
+
rowsToReturn = self.fetchone()
|
|
132
|
+
|
|
133
|
+
if rowsToReturn is None:
|
|
134
|
+
return list()
|
|
135
|
+
return list(rowsToReturn)
|
|
136
|
+
|
|
137
|
+
def fetchall(self):
|
|
138
|
+
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences
|
|
139
|
+
(e.g. a list of tuples).
|
|
140
|
+
An :py:class:`~pyhive.exc.Error` (or subclass) exception is raised if the previous call to
|
|
141
|
+
:py:meth:`execute` did not produce any result set or no call was issued yet.
|
|
142
|
+
"""
|
|
143
|
+
_logger.info("Commons - fetch all")
|
|
144
|
+
return list(iter(self.fetchone, None))
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def arraysize(self):
|
|
148
|
+
"""This read/write attribute specifies the number of rows to fetch at a time with
|
|
149
|
+
:py:meth:`fetchmany`. It defaults to 1 meaning to fetch a single row at a time.
|
|
150
|
+
"""
|
|
151
|
+
return self._arraysize
|
|
152
|
+
|
|
153
|
+
@arraysize.setter
|
|
154
|
+
def arraysize(self, value):
|
|
155
|
+
self._arraysize = value
|
|
156
|
+
|
|
157
|
+
def setinputsizes(self, sizes):
|
|
158
|
+
"""Does nothing by default"""
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
def setoutputsize(self, size, column=None):
|
|
162
|
+
"""Does nothing by default"""
|
|
163
|
+
pass
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Optional DB API Extensions
|
|
167
|
+
#
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def rownumber(self):
|
|
171
|
+
"""This read-only attribute should provide the current 0-based index of the cursor in the
|
|
172
|
+
result set.
|
|
173
|
+
The index can be seen as index of the cursor in a sequence (the result set). The next fetch
|
|
174
|
+
operation will fetch the row indexed by ``rownumber`` in that sequence.
|
|
175
|
+
"""
|
|
176
|
+
return self._rownumber
|
|
177
|
+
|
|
178
|
+
def __next__(self):
|
|
179
|
+
"""Return the next row from the currently executing SQL statement using the same semantics
|
|
180
|
+
as :py:meth:`fetchone`. A ``StopIteration`` exception is raised when the result set is
|
|
181
|
+
exhausted.
|
|
182
|
+
"""
|
|
183
|
+
_logger.info("Commons - fetching the next row")
|
|
184
|
+
one = self.fetchone()
|
|
185
|
+
if one is None:
|
|
186
|
+
raise StopIteration
|
|
187
|
+
else:
|
|
188
|
+
return one
|
|
189
|
+
|
|
190
|
+
next = __next__
|
|
191
|
+
|
|
192
|
+
def __iter__(self):
|
|
193
|
+
"""Return self to make cursors compatible to the iteration protocol."""
|
|
194
|
+
return self
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class DBAPITypeObject(object):
|
|
198
|
+
# Taken from http://www.python.org/dev/peps/pep-0249/#implementation-hints
|
|
199
|
+
def __init__(self, *values):
|
|
200
|
+
self.values = values
|
|
201
|
+
|
|
202
|
+
def __cmp__(self, other):
|
|
203
|
+
if other in self.values:
|
|
204
|
+
return 0
|
|
205
|
+
if other < self.values:
|
|
206
|
+
return 1
|
|
207
|
+
else:
|
|
208
|
+
return -1
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class ParamEscaper(object):
|
|
212
|
+
_DATE_FORMAT = "%Y-%m-%d"
|
|
213
|
+
_TIME_FORMAT = "%H:%M:%S.%f"
|
|
214
|
+
_DATETIME_FORMAT = "{} {}".format(_DATE_FORMAT, _TIME_FORMAT)
|
|
215
|
+
|
|
216
|
+
def escape_args(self, parameters):
|
|
217
|
+
if isinstance(parameters, dict):
|
|
218
|
+
return {k: self.escape_item(v) for k, v in parameters.items()}
|
|
219
|
+
elif isinstance(parameters, (list, tuple)):
|
|
220
|
+
return tuple(self.escape_item(x) for x in parameters)
|
|
221
|
+
else:
|
|
222
|
+
raise ProgrammingError("Unsupported param format: {}".format(parameters))
|
|
223
|
+
|
|
224
|
+
def escape_number(self, item):
|
|
225
|
+
return item
|
|
226
|
+
|
|
227
|
+
def escape_string(self, item):
|
|
228
|
+
# Need to decode UTF-8 because of old sqlalchemy.
|
|
229
|
+
# Newer SQLAlchemy checks dialect.supports_unicode_binds before encoding Unicode strings
|
|
230
|
+
# as byte strings. The old version always encodes Unicode as byte strings, which breaks
|
|
231
|
+
# string formatting here.
|
|
232
|
+
if isinstance(item, bytes):
|
|
233
|
+
item = item.decode('utf-8')
|
|
234
|
+
# This is good enough when backslashes are literal, newlines are just followed, and the way
|
|
235
|
+
# to escape a single quote is to put two single quotes.
|
|
236
|
+
# (i.e. only special character is single quote)
|
|
237
|
+
return "'{}'".format(item.replace("'", "''"))
|
|
238
|
+
|
|
239
|
+
def escape_sequence(self, item):
|
|
240
|
+
l = map(str, map(self.escape_item, item))
|
|
241
|
+
return '(' + ','.join(l) + ')'
|
|
242
|
+
|
|
243
|
+
def escape_datetime(self, item, format, cutoff=0):
|
|
244
|
+
dt_str = item.strftime(format)
|
|
245
|
+
formatted = dt_str[:-cutoff] if cutoff and format.endswith(".%f") else dt_str
|
|
246
|
+
return "'{}'".format(formatted)
|
|
247
|
+
|
|
248
|
+
def escape_item(self, item):
|
|
249
|
+
if item is None:
|
|
250
|
+
return 'NULL'
|
|
251
|
+
elif isinstance(item, (int, float)):
|
|
252
|
+
return self.escape_number(item)
|
|
253
|
+
elif isinstance(item, basestring):
|
|
254
|
+
return self.escape_string(item)
|
|
255
|
+
elif isinstance(item, collections.Iterable):
|
|
256
|
+
return self.escape_sequence(item)
|
|
257
|
+
elif isinstance(item, datetime.datetime):
|
|
258
|
+
return self.escape_datetime(item, self._DATETIME_FORMAT)
|
|
259
|
+
elif isinstance(item, datetime.date):
|
|
260
|
+
return self.escape_datetime(item, self._DATE_FORMAT)
|
|
261
|
+
else:
|
|
262
|
+
raise ProgrammingError("Unsupported object {}".format(item))
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class UniversalSet(object):
|
|
266
|
+
"""set containing everything"""
|
|
267
|
+
|
|
268
|
+
def __contains__(self, item):
|
|
269
|
+
return True
|
e6xdb/constants.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pytz
|
|
2
|
+
|
|
3
|
+
PRIMITIVE_TYPES = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 20, 21}
|
|
4
|
+
COMPLEX_TYPES = {10, 11, 12, 13, 14}
|
|
5
|
+
COLLECTION_TYPES = {10, 11}
|
|
6
|
+
TYPE_NAMES = {
|
|
7
|
+
0: "BOOLEAN",
|
|
8
|
+
1: "TINYINT",
|
|
9
|
+
2: "SMALLINT",
|
|
10
|
+
3: "INT",
|
|
11
|
+
4: "BIGINT",
|
|
12
|
+
5: "FLOAT",
|
|
13
|
+
6: "DOUBLE",
|
|
14
|
+
7: "STRING",
|
|
15
|
+
8: "TIMESTAMP",
|
|
16
|
+
9: "BINARY",
|
|
17
|
+
10: "ARRAY",
|
|
18
|
+
11: "MAP",
|
|
19
|
+
12: "STRUCT",
|
|
20
|
+
13: "UNIONTYPE",
|
|
21
|
+
15: "DECIMAL",
|
|
22
|
+
16: "NULL",
|
|
23
|
+
17: "DATE",
|
|
24
|
+
18: "VARCHAR",
|
|
25
|
+
19: "CHAR",
|
|
26
|
+
20: "INTERVAL_YEAR_MONTH",
|
|
27
|
+
21: "INTERVAL_DAY_TIME",
|
|
28
|
+
}
|
|
29
|
+
CHARACTER_MAXIMUM_LENGTH = "characterMaximumLength"
|
|
30
|
+
PRECISION = "precision"
|
|
31
|
+
SCALE = "scale"
|
|
32
|
+
ZONE = pytz.timezone('UTC')
|
e6xdb/datainputstream.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
import logging
|
|
3
|
+
from e6xdb.date_time_utils import FORMATS, floor_div, floor_mod
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
from e6xdb.constants import ZONE
|
|
6
|
+
|
|
7
|
+
_logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataInputStream:
|
|
11
|
+
def __init__(self, stream):
|
|
12
|
+
self.stream = stream
|
|
13
|
+
|
|
14
|
+
def read_boolean(self):
|
|
15
|
+
return struct.unpack('?', self.stream.read(1))[0]
|
|
16
|
+
|
|
17
|
+
def read_bytes(self, byte_array):
|
|
18
|
+
for i in range(len(byte_array)):
|
|
19
|
+
byte_array[i] = struct.unpack('B', self.stream.read(1))[0]
|
|
20
|
+
return byte_array
|
|
21
|
+
|
|
22
|
+
def read_int_96(self):
|
|
23
|
+
return struct.unpack('B', self.stream.read(12))[0]
|
|
24
|
+
|
|
25
|
+
def read_byte(self):
|
|
26
|
+
return struct.unpack('b', self.stream.read(1))[0]
|
|
27
|
+
|
|
28
|
+
def read_unsigned_byte(self):
|
|
29
|
+
return struct.unpack('B', self.stream.read(1))[0]
|
|
30
|
+
|
|
31
|
+
def read_char(self):
|
|
32
|
+
return chr(struct.unpack('>H', self.stream.read(2))[0])
|
|
33
|
+
|
|
34
|
+
def read_double(self):
|
|
35
|
+
return struct.unpack('>d', self.stream.read(8))[0]
|
|
36
|
+
|
|
37
|
+
def read_float(self):
|
|
38
|
+
return struct.unpack('>f', self.stream.read(4))[0]
|
|
39
|
+
|
|
40
|
+
def read_short(self):
|
|
41
|
+
return struct.unpack('>h', self.stream.read(2))[0]
|
|
42
|
+
|
|
43
|
+
def read_unsigned_short(self):
|
|
44
|
+
return struct.unpack('>H', self.stream.read(2))[0]
|
|
45
|
+
|
|
46
|
+
def read_long(self):
|
|
47
|
+
return struct.unpack('>q', self.stream.read(8))[0]
|
|
48
|
+
|
|
49
|
+
def read_utf(self):
|
|
50
|
+
utf_length = struct.unpack('>H', self.stream.read(2))[0]
|
|
51
|
+
return self.stream.read(utf_length)
|
|
52
|
+
|
|
53
|
+
def read_int(self):
|
|
54
|
+
return struct.unpack('>i', self.stream.read(4))[0]
|
|
55
|
+
|
|
56
|
+
def read_unsigned_int(self):
|
|
57
|
+
return struct.unpack('>I', self.stream.read(4))[0]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class FieldInfo:
|
|
61
|
+
def __init__(self, name, field_type, date_format, zone):
|
|
62
|
+
self.name = name
|
|
63
|
+
self.field_type = field_type
|
|
64
|
+
self.date_format = date_format
|
|
65
|
+
self.zone = zone
|
|
66
|
+
|
|
67
|
+
def get_zone(self):
|
|
68
|
+
if self.field_type == 'DATE' or self.field_type == 'DATETIME':
|
|
69
|
+
return self.zone
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
def get_format(self):
|
|
73
|
+
if self.field_type == 'DATE' or self.field_type == 'DATETIME':
|
|
74
|
+
return self.date_format
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
def get_field_type(self):
|
|
78
|
+
return self.field_type
|
|
79
|
+
|
|
80
|
+
def get_name(self):
|
|
81
|
+
return self.name
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def get_query_columns_info(buffer):
|
|
85
|
+
result_meta_bytes = DataInputStream(buffer)
|
|
86
|
+
rowcount = result_meta_bytes.read_long()
|
|
87
|
+
field_count = result_meta_bytes.read_int()
|
|
88
|
+
columns_description = list()
|
|
89
|
+
|
|
90
|
+
for i in range(field_count):
|
|
91
|
+
name = result_meta_bytes.read_utf().decode()
|
|
92
|
+
field_type = result_meta_bytes.read_utf().decode()
|
|
93
|
+
zone = result_meta_bytes.read_utf().decode()
|
|
94
|
+
date_format = result_meta_bytes.read_utf().decode()
|
|
95
|
+
field_info = FieldInfo(name, field_type, date_format, zone)
|
|
96
|
+
columns_description.append(field_info)
|
|
97
|
+
return rowcount, columns_description
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def read_values_from_array(query_columns_description: list, dis: DataInputStream) -> list:
|
|
101
|
+
value_array = list()
|
|
102
|
+
for i in query_columns_description:
|
|
103
|
+
dtype = i.get_field_type()
|
|
104
|
+
isPresent = dis.read_byte()
|
|
105
|
+
date_format = i.get_format()
|
|
106
|
+
if isPresent == 0:
|
|
107
|
+
value_array.append(None)
|
|
108
|
+
continue
|
|
109
|
+
try:
|
|
110
|
+
if dtype == "LONG":
|
|
111
|
+
value_array.append(dis.read_long())
|
|
112
|
+
elif dtype == "DATE":
|
|
113
|
+
epoch_seconds = floor_div(dis.read_long(), 1000_000)
|
|
114
|
+
date = datetime.fromtimestamp(epoch_seconds, ZONE)
|
|
115
|
+
value_array.append(date.strftime("%Y-%m-%d"))
|
|
116
|
+
elif dtype == "DATETIME":
|
|
117
|
+
epoch_micros = dis.read_long()
|
|
118
|
+
epoch_seconds = floor_div(epoch_micros, 1000_000)
|
|
119
|
+
micros_of_the_day = floor_mod(epoch_micros, 1000_000)
|
|
120
|
+
date_time = datetime.fromtimestamp(epoch_seconds, ZONE)
|
|
121
|
+
date_time = date_time + timedelta(microseconds=micros_of_the_day)
|
|
122
|
+
value_array.append(date_time.strftime("%Y-%m-%d %H:%M:%S"))
|
|
123
|
+
elif dtype == "STRING" or dtype == "ARRAY" or dtype == "MAP" or dtype == "STRUCT":
|
|
124
|
+
value_array.append(dis.read_utf().decode())
|
|
125
|
+
elif dtype == "INT":
|
|
126
|
+
value_array.append(dis.read_int())
|
|
127
|
+
elif dtype == "DOUBLE":
|
|
128
|
+
value_array.append(dis.read_double())
|
|
129
|
+
elif dtype == "BINARY":
|
|
130
|
+
value_array.append(dis.read_utf())
|
|
131
|
+
elif dtype == "FLOAT":
|
|
132
|
+
value_array.append(dis.read_float())
|
|
133
|
+
elif dtype == "CHAR":
|
|
134
|
+
value_array.append(dis.read_char())
|
|
135
|
+
elif dtype == "BOOLEAN":
|
|
136
|
+
value_array.append(dis.read_boolean())
|
|
137
|
+
elif dtype == "SHORT":
|
|
138
|
+
value_array.append(dis.read_short())
|
|
139
|
+
elif dtype == "BYTE":
|
|
140
|
+
value_array.append(dis.read_byte())
|
|
141
|
+
elif dtype == "INT96":
|
|
142
|
+
julian_day = dis.read_int()
|
|
143
|
+
time = dis.read_long()
|
|
144
|
+
date_time = datetime.fromtimestamp((julian_day - 2440588) * 86400)
|
|
145
|
+
date_time_with_nanos = date_time + timedelta(microseconds=(time / 1000))
|
|
146
|
+
value_array.append(date_time_with_nanos)
|
|
147
|
+
elif dtype == "INTEGER":
|
|
148
|
+
value_array.append(dis.read_int())
|
|
149
|
+
except Exception as e:
|
|
150
|
+
_logger.error(e)
|
|
151
|
+
value_array.append('Failed to parse.')
|
|
152
|
+
|
|
153
|
+
return value_array
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def read_rows_from_batch(query_columns_description: list, dis: DataInputStream):
|
|
157
|
+
is_row_present = dis.read_byte()
|
|
158
|
+
if not is_row_present:
|
|
159
|
+
return None
|
|
160
|
+
rows = list()
|
|
161
|
+
while is_row_present == 1:
|
|
162
|
+
if is_row_present:
|
|
163
|
+
row = read_values_from_array(query_columns_description, dis)
|
|
164
|
+
rows.append(row)
|
|
165
|
+
# if rows become 1000, break it
|
|
166
|
+
# if len(rows) == 1000:
|
|
167
|
+
# _logger.info("Read Batch - Breaking the loop after 1000 records")
|
|
168
|
+
# break
|
|
169
|
+
is_row_present = dis.read_byte()
|
|
170
|
+
return rows
|
e6xdb/date_time_utils.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
TIME_ZONES = {
|
|
2
|
+
"+12:00": ["Pacific/Kwajalein", "Pacific/Wallis", "Pacific/Funafuti", "Pacific/Nauru", "Kwajalein", "Pacific/Wake",
|
|
3
|
+
"Pacific/Norfolk", "Pacific/Tarawa", "Asia/Kamchatka", "Etc/GMT-12", "Asia/Anadyr", "Pacific/Majuro", ],
|
|
4
|
+
"+14:00": ["Pacific/Kiritimati", "Etc/GMT-14", ],
|
|
5
|
+
"UTC": ["UTC"],
|
|
6
|
+
"-01:00": ["Etc/GMT+1", "Atlantic/Cape_Verde", "Atlantic/Azores", "America/Scoresbysund", ],
|
|
7
|
+
"-03:00": ["Chile/Continental", "America/Miquelon", "America/Argentina/Catamarca", "America/Argentina/Cordoba",
|
|
8
|
+
"America/Araguaina", "America/Argentina/Salta", "Etc/GMT+3", "America/Montevideo", "Brazil/East",
|
|
9
|
+
"America/Argentina/Mendoza", "America/Argentina/Rio_Gallegos", "America/Catamarca", "America/Godthab",
|
|
10
|
+
"America/Cordoba", "America/Sao_Paulo", "America/Argentina/Jujuy", "America/Cayenne", "America/Recife",
|
|
11
|
+
"America/Buenos_Aires", "America/Paramaribo", "America/Mendoza", "America/Santarem", "America/Asuncion",
|
|
12
|
+
"America/Maceio", "Atlantic/Stanley", "Antarctica/Rothera", "America/Argentina/San_Luis",
|
|
13
|
+
"America/Santiago", "America/Argentina/Ushuaia", "Antarctica/Palmer", "America/Punta_Arenas",
|
|
14
|
+
"America/Fortaleza", "America/Argentina/La_Rioja", "America/Belem", "America/Jujuy", "America/Bahia",
|
|
15
|
+
"America/Argentina/San_Juan", "America/Argentina/ComodRivadavia", "America/Argentina/Tucuman",
|
|
16
|
+
"America/Nuuk", "America/Rosario", "America/Argentina/Buenos_Aires", ],
|
|
17
|
+
"-09:00": ["Etc/GMT+9", "US/Alaska", "America/Juneau", "America/Metlakatla", "Pacific/Gambier", "America/Yakutat",
|
|
18
|
+
"America/Sitka", "SystemV/YST9", "America/Anchorage", "America/Nome", "SystemV/YST9YDT", ],
|
|
19
|
+
"-07:00": ["Canada/Yukon", "Etc/GMT+7", "US/Arizona", "Mexico/BajaSur", "America/Dawson_Creek", "America/Denver",
|
|
20
|
+
"America/Yellowknife", "America/Inuvik", "America/Mazatlan", "SystemV/MST7", "America/Boise",
|
|
21
|
+
"America/Dawson", "MST7MDT", "America/Chihuahua", "America/Ojinaga", "US/Mountain", "America/Creston",
|
|
22
|
+
"America/Edmonton", "America/Hermosillo", "Canada/Mountain", "America/Cambridge_Bay", "Navajo",
|
|
23
|
+
"America/Phoenix", "America/Whitehorse", "SystemV/MST7MDT", "America/Fort_Nelson", "America/Shiprock", ],
|
|
24
|
+
"-05:00": ["America/Panama", "America/Indiana/Petersburg", "America/Eirunepe", "America/Grand_Turk", "Cuba",
|
|
25
|
+
"Etc/GMT+5", "Pacific/Easter", "America/Fort_Wayne", "America/Havana", "America/Porto_Acre",
|
|
26
|
+
"US/Michigan", "America/Louisville", "America/Guayaquil", "America/Indiana/Vevay",
|
|
27
|
+
"America/Indiana/Vincennes", "America/Indianapolis", "America/Iqaluit", "America/Kentucky/Louisville",
|
|
28
|
+
"EST5EDT", "America/Nassau", "America/Jamaica", "America/Atikokan", "America/Kentucky/Monticello",
|
|
29
|
+
"America/Coral_Harbour", "America/Cayman", "Chile/EasterIsland", "America/Indiana/Indianapolis",
|
|
30
|
+
"America/Thunder_Bay", "America/Indiana/Marengo", "America/Bogota", "SystemV/EST5", "US/Eastern",
|
|
31
|
+
"Canada/Eastern", "America/Port-au-Prince", "America/Nipigon", "Brazil/Acre", "US/East-Indiana",
|
|
32
|
+
"America/Cancun", "America/Lima", "America/Rio_Branco", "America/Detroit", "Jamaica",
|
|
33
|
+
"America/Pangnirtung", "America/Montreal", "America/Indiana/Winamac", "America/New_York",
|
|
34
|
+
"America/Toronto", "SystemV/EST5EDT", ],
|
|
35
|
+
"+03:00": ["Asia/Aden", "Africa/Nairobi", "Europe/Istanbul", "Etc/GMT-3", "Indian/Comoro", "Antarctica/Syowa",
|
|
36
|
+
"Africa/Mogadishu", "Africa/Asmera", "Asia/Istanbul", "Europe/Moscow", "Africa/Djibouti",
|
|
37
|
+
"Europe/Simferopol", "Africa/Asmara", "Asia/Baghdad", "Africa/Dar_es_Salaam", "Africa/Addis_Ababa",
|
|
38
|
+
"Asia/Riyadh", "Asia/Kuwait", "Europe/Kirov", "Africa/Kampala", "Europe/Minsk", "Asia/Qatar",
|
|
39
|
+
"Asia/Bahrain", "Indian/Antananarivo", "Indian/Mayotte", "Europe/Volgograd", "Turkey", "W-SU", ],
|
|
40
|
+
"+01:00": ["Europe/Brussels", "Europe/Warsaw", "CET", "Etc/GMT-1", "Europe/Luxembourg", "Africa/Tunis",
|
|
41
|
+
"Europe/Malta", "Europe/Busingen", "Africa/Malabo", "Europe/Skopje", "Europe/Sarajevo", "Africa/Lagos",
|
|
42
|
+
"Europe/Rome", "Africa/Algiers", "Europe/Zurich", "Europe/Gibraltar", "Europe/Vaduz", "Europe/Ljubljana",
|
|
43
|
+
"Europe/Berlin", "Europe/Stockholm", "Europe/Budapest", "Europe/Zagreb", "Europe/Paris",
|
|
44
|
+
"Africa/Ndjamena", "Africa/Ceuta", "Europe/Prague", "Europe/Copenhagen", "Europe/Vienna",
|
|
45
|
+
"Europe/Tirane", "MET", "Europe/Amsterdam", "Africa/Libreville", "Africa/El_Aaiun", "Europe/San_Marino",
|
|
46
|
+
"Africa/Douala", "Africa/Brazzaville", "Africa/Porto-Novo", "Poland", "Europe/Andorra", "Europe/Oslo",
|
|
47
|
+
"Europe/Podgorica", "Africa/Casablanca", "Africa/Luanda", "Atlantic/Jan_Mayen", "Africa/Kinshasa",
|
|
48
|
+
"Europe/Madrid", "Africa/Bangui", "Europe/Belgrade", "Africa/Niamey", "Europe/Bratislava",
|
|
49
|
+
"Arctic/Longyearbyen", "Europe/Vatican", "Europe/Monaco", ],
|
|
50
|
+
"+04:30": ["Asia/Kabul", ],
|
|
51
|
+
"+07:00": ["Asia/Pontianak", "Etc/GMT-7", "Asia/Phnom_Penh", "Asia/Novosibirsk", "Antarctica/Davis", "Asia/Tomsk",
|
|
52
|
+
"Asia/Jakarta", "Asia/Barnaul", "Indian/Christmas", "Asia/Ho_Chi_Minh", "Asia/Hovd", "Asia/Bangkok",
|
|
53
|
+
"Asia/Vientiane", "Asia/Novokuznetsk", "Asia/Krasnoyarsk", "Asia/Saigon", ],
|
|
54
|
+
"+05:45": ["Asia/Kathmandu", "Asia/Katmandu", ],
|
|
55
|
+
"+05:00": ["Asia/Aqtau", "Etc/GMT-5", "Asia/Samarkand", "Asia/Karachi", "Asia/Yekaterinburg", "Asia/Dushanbe",
|
|
56
|
+
"Indian/Maldives", "Asia/Oral", "Asia/Tashkent", "Antarctica/Mawson", "Asia/Qyzylorda", "Asia/Aqtobe",
|
|
57
|
+
"Asia/Ashkhabad", "Asia/Ashgabat", "Asia/Atyrau", "Indian/Kerguelen", ],
|
|
58
|
+
"+06:30": ["Asia/Yangon", "Asia/Rangoon", "Indian/Cocos", ],
|
|
59
|
+
"+10:00": ["Pacific/Yap", "Pacific/Port_Moresby", "Pacific/Chuuk", "Australia/Queensland", "Pacific/Guam",
|
|
60
|
+
"Pacific/Truk", "Asia/Vladivostok", "Pacific/Saipan", "Antarctica/DumontDUrville", "Australia/Brisbane",
|
|
61
|
+
"Etc/GMT-10", "Asia/Ust-Nera", "Australia/Lindeman", ],
|
|
62
|
+
"+09:00": ["Etc/GMT-9", "Pacific/Palau", "Asia/Chita", "Asia/Dili", "Asia/Jayapura", "Asia/Yakutsk",
|
|
63
|
+
"Asia/Pyongyang", "ROK", "Asia/Seoul", "Asia/Khandyga", "Japan", "Asia/Tokyo", ],
|
|
64
|
+
"Z": ["UTC", "Europe/London", "GMT", "Etc/GMT-0", "Europe/Jersey", "Atlantic/St_Helena", "Europe/Guernsey",
|
|
65
|
+
"Europe/Isle_of_Man", "Etc/GMT+0", "Africa/Banjul", "Etc/GMT", "Africa/Freetown", "GB-Eire", "Africa/Bamako",
|
|
66
|
+
"GB", "Africa/Conakry", "Portugal", "Universal", "Africa/Sao_Tome", "Africa/Nouakchott", "Antarctica/Troll",
|
|
67
|
+
"UTC", "Etc/Universal", "Atlantic/Faeroe", "Africa/Abidjan", "Eire", "Africa/Accra", "Atlantic/Faroe",
|
|
68
|
+
"Etc/UCT", "GMT0", "Europe/Dublin", "Zulu", "Africa/Ouagadougou", "Atlantic/Reykjavik", "Atlantic/Madeira",
|
|
69
|
+
"Etc/Zulu", "Iceland", "Europe/Lisbon", "Atlantic/Canary", "Africa/Lome", "Greenwich", "Europe/Belfast",
|
|
70
|
+
"Etc/GMT0", "America/Danmarkshavn", "Africa/Dakar", "Africa/Bissau", "WET", "Etc/Greenwich",
|
|
71
|
+
"Africa/Timbuktu", "UCT", "Africa/Monrovia", "Etc/UTC", ],
|
|
72
|
+
"-11:00": ["Pacific/Pago_Pago", "Pacific/Samoa", "Pacific/Niue", "US/Samoa", "Etc/GMT+11", "Pacific/Midway", ],
|
|
73
|
+
"-06:00": ["America/El_Salvador", "America/Guatemala", "America/Belize", "America/Managua", "America/Chicago",
|
|
74
|
+
"America/Tegucigalpa", "Etc/GMT+6", "America/Regina", "Mexico/General", "America/Rankin_Inlet",
|
|
75
|
+
"US/Central", "Pacific/Galapagos", "America/Rainy_River", "America/Swift_Current", "America/Costa_Rica",
|
|
76
|
+
"America/Indiana/Knox", "America/North_Dakota/Beulah", "America/Monterrey", "SystemV/CST6",
|
|
77
|
+
"America/North_Dakota/Center", "America/Indiana/Tell_City", "America/Mexico_City", "America/Matamoros",
|
|
78
|
+
"CST6CDT", "America/Knox_IN", "America/Menominee", "America/Resolute", "Canada/Central",
|
|
79
|
+
"America/Bahia_Banderas", "US/Indiana-Starke", "SystemV/CST6CDT", "America/Merida",
|
|
80
|
+
"Canada/Saskatchewan", "America/North_Dakota/New_Salem", "America/Winnipeg", ],
|
|
81
|
+
"-03:30": ["America/St_Johns", "Canada/Newfoundland", ],
|
|
82
|
+
"+13:45": ["NZ-CHAT", "Pacific/Chatham", ],
|
|
83
|
+
"+10:30": ["Australia/Yancowinna", "Australia/Adelaide", "Australia/Broken_Hill", "Australia/South", ],
|
|
84
|
+
"+11:00": ["Australia/Hobart", "Australia/Tasmania", "Australia/ACT", "Pacific/Ponape", "Pacific/Bougainville",
|
|
85
|
+
"Australia/Victoria", "Antarctica/Macquarie", "Antarctica/Casey", "Australia/Canberra",
|
|
86
|
+
"Australia/Currie", "Australia/Lord_Howe", "Australia/NSW", "Pacific/Pohnpei", "Pacific/Efate",
|
|
87
|
+
"Asia/Magadan", "Pacific/Kosrae", "Australia/Sydney", "Australia/LHI", "Asia/Sakhalin", "Pacific/Noumea",
|
|
88
|
+
"Etc/GMT-11", "Asia/Srednekolymsk", "Australia/Melbourne", "Pacific/Guadalcanal", ],
|
|
89
|
+
"+13:00": ["Pacific/Fakaofo", "Antarctica/McMurdo", "Pacific/Fiji", "Pacific/Enderbury", "NZ", "Pacific/Apia",
|
|
90
|
+
"Antarctica/South_Pole", "Pacific/Kanton", "Pacific/Auckland", "Pacific/Tongatapu", "Etc/GMT-13", ],
|
|
91
|
+
"-09:30": ["Pacific/Marquesas", ],
|
|
92
|
+
"-08:00": ["Etc/GMT+8", "Canada/Pacific", "PST8PDT", "Pacific/Pitcairn", "Mexico/BajaNorte", "America/Tijuana",
|
|
93
|
+
"SystemV/PST8", "America/Santa_Isabel", "America/Vancouver", "America/Ensenada", "SystemV/PST8PDT",
|
|
94
|
+
"America/Los_Angeles", "US/Pacific", ],
|
|
95
|
+
"-02:00": ["Etc/GMT+2", "America/Noronha", "Brazil/DeNoronha", "Atlantic/South_Georgia", ],
|
|
96
|
+
"-04:00": ["America/Cuiaba", "America/Marigot", "Canada/Atlantic", "Etc/GMT+4", "America/Manaus",
|
|
97
|
+
"America/St_Thomas", "America/Anguilla", "America/Barbados", "America/Curacao", "America/Guyana",
|
|
98
|
+
"America/Martinique", "America/Puerto_Rico", "America/Port_of_Spain", "SystemV/AST4",
|
|
99
|
+
"America/Kralendijk", "America/Antigua", "America/Moncton", "America/St_Vincent", "America/Dominica",
|
|
100
|
+
"Atlantic/Bermuda", "Brazil/West", "America/Aruba", "America/Halifax", "America/La_Paz",
|
|
101
|
+
"America/Blanc-Sablon", "America/Santo_Domingo", "America/Glace_Bay", "America/St_Barthelemy",
|
|
102
|
+
"America/St_Lucia", "America/Montserrat", "America/Lower_Princes", "America/Thule", "America/Tortola",
|
|
103
|
+
"America/Porto_Velho", "America/Campo_Grande", "America/Goose_Bay", "America/Virgin",
|
|
104
|
+
"America/Boa_Vista", "America/Grenada", "America/St_Kitts", "America/Caracas", "America/Guadeloupe",
|
|
105
|
+
"SystemV/AST4ADT", ],
|
|
106
|
+
"+02:00": ["Africa/Cairo", "Africa/Mbabane", "Etc/GMT-2", "Europe/Zaporozhye", "Libya", "Africa/Kigali",
|
|
107
|
+
"Africa/Tripoli", "Israel", "Europe/Kaliningrad", "Africa/Windhoek", "Europe/Bucharest",
|
|
108
|
+
"Europe/Mariehamn", "Africa/Lubumbashi", "Europe/Tiraspol", "Europe/Chisinau", "Europe/Helsinki",
|
|
109
|
+
"Asia/Beirut", "Asia/Tel_Aviv", "Europe/Sofia", "Africa/Gaborone", "Asia/Gaza", "Europe/Riga",
|
|
110
|
+
"Africa/Maputo", "Asia/Damascus", "Europe/Uzhgorod", "Asia/Jerusalem", "Africa/Bujumbura", "Europe/Kiev",
|
|
111
|
+
"Europe/Vilnius", "Africa/Maseru", "Africa/Blantyre", "Africa/Lusaka", "Africa/Harare", "Europe/Tallinn",
|
|
112
|
+
"Africa/Khartoum", "Africa/Johannesburg", "Africa/Juba", "Asia/Nicosia", "Asia/Famagusta", "EET",
|
|
113
|
+
"Asia/Hebron", "Egypt", "Asia/Amman", "Europe/Nicosia", "Europe/Athens", ],
|
|
114
|
+
"+03:30": ["Iran", "Asia/Tehran", ],
|
|
115
|
+
"+04:00": ["Asia/Yerevan", "Etc/GMT-4", "Asia/Dubai", "Indian/Reunion", "Indian/Mauritius", "Europe/Saratov",
|
|
116
|
+
"Europe/Samara", "Indian/Mahe", "Asia/Baku", "Asia/Muscat", "Europe/Astrakhan", "Asia/Tbilisi",
|
|
117
|
+
"Europe/Ulyanovsk", ],
|
|
118
|
+
"+06:00": ["Asia/Kashgar", "Etc/GMT-6", "Asia/Almaty", "Asia/Dacca", "Asia/Omsk", "Asia/Dhaka", "Indian/Chagos",
|
|
119
|
+
"Asia/Qostanay", "Asia/Bishkek", "Antarctica/Vostok", "Asia/Urumqi", "Asia/Thimbu", "Asia/Thimphu", ],
|
|
120
|
+
"+08:45": ["Australia/Eucla", ],
|
|
121
|
+
"+08:00": ["Asia/Kuching", "Asia/Chungking", "Etc/GMT-8", "Australia/Perth", "Asia/Macao", "Asia/Macau",
|
|
122
|
+
"Asia/Choibalsan", "Asia/Shanghai", "Asia/Ulan_Bator", "Asia/Chongqing", "Asia/Ulaanbaatar",
|
|
123
|
+
"Asia/Taipei", "Asia/Manila", "PRC", "Asia/Ujung_Pandang", "Asia/Harbin", "Singapore", "Asia/Brunei",
|
|
124
|
+
"Australia/West", "Asia/Hong_Kong", "Asia/Makassar", "Hongkong", "Asia/Kuala_Lumpur", "Asia/Irkutsk",
|
|
125
|
+
"Asia/Singapore", ],
|
|
126
|
+
"-12:00": ["Etc/GMT+12", ],
|
|
127
|
+
"+05:30": ["Asia/Kolkata", "Asia/Colombo", "Asia/Calcutta", ],
|
|
128
|
+
"+09:30": ["Australia/North", "Australia/Darwin", ],
|
|
129
|
+
"-10:00": ["Pacific/Honolulu", "Pacific/Rarotonga", "Pacific/Tahiti", "Pacific/Johnston", "America/Atka",
|
|
130
|
+
"US/Hawaii", "SystemV/HST10", "America/Adak", "US/Aleutian", "Etc/GMT+10", ],
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
FORMATS = {
|
|
135
|
+
"yyyy": "%Y",
|
|
136
|
+
"dd": "%d",
|
|
137
|
+
"MM": "%m",
|
|
138
|
+
"HH": "%H",
|
|
139
|
+
"mm": "%M",
|
|
140
|
+
"ss": "%S"
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def floor_div(x, y):
|
|
145
|
+
q = x // y
|
|
146
|
+
if x ^ y < 0 and q * y != x:
|
|
147
|
+
return q - 1
|
|
148
|
+
return q
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def floor_mod(x, y):
|
|
152
|
+
r = x % y
|
|
153
|
+
if (x ^ y) < 0 and r != 0:
|
|
154
|
+
return r + y
|
|
155
|
+
return r
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def get_format(str_format):
|
|
159
|
+
if str_format is None or len(str_format) == 0:
|
|
160
|
+
return "%Y-%m-%d %H:%M:%S"
|
|
161
|
+
return FORMATS[str_format]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def get_zone(zone):
|
|
165
|
+
if zone is None or len(zone) == 0:
|
|
166
|
+
return "UTC"
|
|
167
|
+
return TIME_ZONES[zone][0]
|