real-ladybug 0.0.1.dev1__cp312-cp312-win_amd64.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.

Potentially problematic release.


This version of real-ladybug might be problematic. Click here for more details.

Files changed (114) hide show
  1. real_ladybug/__init__.py +83 -0
  2. real_ladybug/_lbug.cp312-win_amd64.pyd +0 -0
  3. real_ladybug/_lbug.exp +0 -0
  4. real_ladybug/_lbug.lib +0 -0
  5. real_ladybug/async_connection.py +226 -0
  6. real_ladybug/connection.py +323 -0
  7. real_ladybug/constants.py +7 -0
  8. real_ladybug/database.py +307 -0
  9. real_ladybug/prepared_statement.py +51 -0
  10. real_ladybug/py.typed +0 -0
  11. real_ladybug/query_result.py +511 -0
  12. real_ladybug/torch_geometric_feature_store.py +185 -0
  13. real_ladybug/torch_geometric_graph_store.py +131 -0
  14. real_ladybug/torch_geometric_result_converter.py +282 -0
  15. real_ladybug/types.py +39 -0
  16. real_ladybug-0.0.1.dev1.dist-info/METADATA +88 -0
  17. real_ladybug-0.0.1.dev1.dist-info/RECORD +114 -0
  18. real_ladybug-0.0.1.dev1.dist-info/WHEEL +5 -0
  19. real_ladybug-0.0.1.dev1.dist-info/licenses/LICENSE +21 -0
  20. real_ladybug-0.0.1.dev1.dist-info/top_level.txt +3 -0
  21. real_ladybug-0.0.1.dev1.dist-info/zip-safe +1 -0
  22. real_ladybug-source/scripts/antlr4/hash.py +2 -0
  23. real_ladybug-source/scripts/antlr4/keywordhandler.py +47 -0
  24. real_ladybug-source/scripts/collect-extensions.py +68 -0
  25. real_ladybug-source/scripts/collect-single-file-header.py +126 -0
  26. real_ladybug-source/scripts/export-dbs.py +101 -0
  27. real_ladybug-source/scripts/export-import-test.py +345 -0
  28. real_ladybug-source/scripts/extension/purge-beta.py +34 -0
  29. real_ladybug-source/scripts/generate-cpp-docs/collect_files.py +122 -0
  30. real_ladybug-source/scripts/generate-tinysnb.py +34 -0
  31. real_ladybug-source/scripts/get-clangd-diagnostics.py +233 -0
  32. real_ladybug-source/scripts/migrate-lbug-db.py +308 -0
  33. real_ladybug-source/scripts/multiplatform-test-helper/collect-results.py +71 -0
  34. real_ladybug-source/scripts/multiplatform-test-helper/notify-discord.py +68 -0
  35. real_ladybug-source/scripts/pip-package/package_tar.py +90 -0
  36. real_ladybug-source/scripts/pip-package/setup.py +130 -0
  37. real_ladybug-source/scripts/run-clang-format.py +408 -0
  38. real_ladybug-source/scripts/setup-extension-repo.py +67 -0
  39. real_ladybug-source/scripts/test-simsimd-dispatch.py +45 -0
  40. real_ladybug-source/scripts/update-nightly-build-version.py +81 -0
  41. real_ladybug-source/third_party/brotli/scripts/dictionary/step-01-download-rfc.py +16 -0
  42. real_ladybug-source/third_party/brotli/scripts/dictionary/step-02-rfc-to-bin.py +34 -0
  43. real_ladybug-source/third_party/brotli/scripts/dictionary/step-03-validate-bin.py +35 -0
  44. real_ladybug-source/third_party/brotli/scripts/dictionary/step-04-generate-java-literals.py +85 -0
  45. real_ladybug-source/third_party/pybind11/tools/codespell_ignore_lines_from_errors.py +35 -0
  46. real_ladybug-source/third_party/pybind11/tools/libsize.py +36 -0
  47. real_ladybug-source/third_party/pybind11/tools/make_changelog.py +63 -0
  48. real_ladybug-source/tools/python_api/build/real_ladybug/__init__.py +83 -0
  49. real_ladybug-source/tools/python_api/build/real_ladybug/async_connection.py +226 -0
  50. real_ladybug-source/tools/python_api/build/real_ladybug/connection.py +323 -0
  51. real_ladybug-source/tools/python_api/build/real_ladybug/constants.py +7 -0
  52. real_ladybug-source/tools/python_api/build/real_ladybug/database.py +307 -0
  53. real_ladybug-source/tools/python_api/build/real_ladybug/prepared_statement.py +51 -0
  54. real_ladybug-source/tools/python_api/build/real_ladybug/py.typed +0 -0
  55. real_ladybug-source/tools/python_api/build/real_ladybug/query_result.py +511 -0
  56. real_ladybug-source/tools/python_api/build/real_ladybug/torch_geometric_feature_store.py +185 -0
  57. real_ladybug-source/tools/python_api/build/real_ladybug/torch_geometric_graph_store.py +131 -0
  58. real_ladybug-source/tools/python_api/build/real_ladybug/torch_geometric_result_converter.py +282 -0
  59. real_ladybug-source/tools/python_api/build/real_ladybug/types.py +39 -0
  60. real_ladybug-source/tools/python_api/src_py/__init__.py +83 -0
  61. real_ladybug-source/tools/python_api/src_py/async_connection.py +226 -0
  62. real_ladybug-source/tools/python_api/src_py/connection.py +323 -0
  63. real_ladybug-source/tools/python_api/src_py/constants.py +7 -0
  64. real_ladybug-source/tools/python_api/src_py/database.py +307 -0
  65. real_ladybug-source/tools/python_api/src_py/prepared_statement.py +51 -0
  66. real_ladybug-source/tools/python_api/src_py/py.typed +0 -0
  67. real_ladybug-source/tools/python_api/src_py/query_result.py +511 -0
  68. real_ladybug-source/tools/python_api/src_py/torch_geometric_feature_store.py +185 -0
  69. real_ladybug-source/tools/python_api/src_py/torch_geometric_graph_store.py +131 -0
  70. real_ladybug-source/tools/python_api/src_py/torch_geometric_result_converter.py +282 -0
  71. real_ladybug-source/tools/python_api/src_py/types.py +39 -0
  72. real_ladybug-source/tools/python_api/test/conftest.py +230 -0
  73. real_ladybug-source/tools/python_api/test/disabled_test_extension.py +73 -0
  74. real_ladybug-source/tools/python_api/test/ground_truth.py +430 -0
  75. real_ladybug-source/tools/python_api/test/test_arrow.py +694 -0
  76. real_ladybug-source/tools/python_api/test/test_async_connection.py +159 -0
  77. real_ladybug-source/tools/python_api/test/test_blob_parameter.py +145 -0
  78. real_ladybug-source/tools/python_api/test/test_connection.py +49 -0
  79. real_ladybug-source/tools/python_api/test/test_database.py +234 -0
  80. real_ladybug-source/tools/python_api/test/test_datatype.py +372 -0
  81. real_ladybug-source/tools/python_api/test/test_df.py +564 -0
  82. real_ladybug-source/tools/python_api/test/test_dict.py +112 -0
  83. real_ladybug-source/tools/python_api/test/test_exception.py +54 -0
  84. real_ladybug-source/tools/python_api/test/test_fsm.py +227 -0
  85. real_ladybug-source/tools/python_api/test/test_get_header.py +49 -0
  86. real_ladybug-source/tools/python_api/test/test_helper.py +8 -0
  87. real_ladybug-source/tools/python_api/test/test_issue.py +147 -0
  88. real_ladybug-source/tools/python_api/test/test_iteration.py +96 -0
  89. real_ladybug-source/tools/python_api/test/test_networkx.py +437 -0
  90. real_ladybug-source/tools/python_api/test/test_parameter.py +340 -0
  91. real_ladybug-source/tools/python_api/test/test_prepared_statement.py +117 -0
  92. real_ladybug-source/tools/python_api/test/test_query_result.py +54 -0
  93. real_ladybug-source/tools/python_api/test/test_query_result_close.py +44 -0
  94. real_ladybug-source/tools/python_api/test/test_scan_pandas.py +676 -0
  95. real_ladybug-source/tools/python_api/test/test_scan_pandas_pyarrow.py +714 -0
  96. real_ladybug-source/tools/python_api/test/test_scan_polars.py +165 -0
  97. real_ladybug-source/tools/python_api/test/test_scan_pyarrow.py +167 -0
  98. real_ladybug-source/tools/python_api/test/test_timeout.py +11 -0
  99. real_ladybug-source/tools/python_api/test/test_torch_geometric.py +640 -0
  100. real_ladybug-source/tools/python_api/test/test_torch_geometric_remote_backend.py +111 -0
  101. real_ladybug-source/tools/python_api/test/test_udf.py +207 -0
  102. real_ladybug-source/tools/python_api/test/test_version.py +6 -0
  103. real_ladybug-source/tools/python_api/test/test_wal.py +80 -0
  104. real_ladybug-source/tools/python_api/test/type_aliases.py +10 -0
  105. real_ladybug-source/tools/rust_api/update_version.py +47 -0
  106. real_ladybug-source/tools/shell/test/conftest.py +218 -0
  107. real_ladybug-source/tools/shell/test/test_helper.py +60 -0
  108. real_ladybug-source/tools/shell/test/test_shell_basics.py +325 -0
  109. real_ladybug-source/tools/shell/test/test_shell_commands.py +656 -0
  110. real_ladybug-source/tools/shell/test/test_shell_control_edit.py +438 -0
  111. real_ladybug-source/tools/shell/test/test_shell_control_search.py +468 -0
  112. real_ladybug-source/tools/shell/test/test_shell_esc_edit.py +232 -0
  113. real_ladybug-source/tools/shell/test/test_shell_esc_search.py +162 -0
  114. real_ladybug-source/tools/shell/test/test_shell_flags.py +645 -0
@@ -0,0 +1,564 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ import math
5
+ from decimal import Decimal
6
+ from typing import Any
7
+ from uuid import UUID
8
+
9
+ import real_ladybug as lb
10
+ import pytz
11
+ from pandas import Timedelta, Timestamp
12
+ from type_aliases import ConnDB
13
+ from real_ladybug.constants import ID, LABEL, SRC, DST, NODES, RELS
14
+
15
+
16
+ def test_to_df(conn_db_readonly: ConnDB) -> None:
17
+ conn, _ = conn_db_readonly
18
+
19
+ def _test_person_to_df(conn: lb.Connection) -> None:
20
+ query = "MATCH (p:person) return p.* ORDER BY p.ID"
21
+ pd = conn.execute(query).get_as_df()
22
+ assert pd["p.ID"].tolist() == [0, 2, 3, 5, 7, 8, 9, 10]
23
+ assert str(pd["p.ID"].dtype) == "int64"
24
+ assert pd["p.fName"].tolist() == [
25
+ "Alice",
26
+ "Bob",
27
+ "Carol",
28
+ "Dan",
29
+ "Elizabeth",
30
+ "Farooq",
31
+ "Greg",
32
+ "Hubert Blaine Wolfeschlegelsteinhausenbergerdorff",
33
+ ]
34
+ assert str(pd["p.fName"].dtype) == "object"
35
+ assert pd["p.gender"].tolist() == [1, 2, 1, 2, 1, 2, 2, 2]
36
+ assert str(pd["p.gender"].dtype) == "int64"
37
+ assert pd["p.isStudent"].tolist() == [
38
+ True,
39
+ True,
40
+ False,
41
+ False,
42
+ False,
43
+ True,
44
+ False,
45
+ False,
46
+ ]
47
+ assert str(pd["p.isStudent"].dtype) == "bool"
48
+ assert pd["p.eyeSight"].tolist() == [5.0, 5.1, 5.0, 4.8, 4.7, 4.5, 4.9, 4.9]
49
+ assert str(pd["p.eyeSight"].dtype) == "float64"
50
+ assert pd["p.birthdate"].tolist() == [
51
+ Timestamp("1900-01-01"),
52
+ Timestamp("1900-01-01"),
53
+ Timestamp("1940-06-22"),
54
+ Timestamp("1950-07-23 "),
55
+ Timestamp("1980-10-26"),
56
+ Timestamp("1980-10-26"),
57
+ Timestamp("1980-10-26"),
58
+ Timestamp("1990-11-27"),
59
+ ]
60
+ assert str(pd["p.birthdate"].dtype) == "datetime64[us]"
61
+ assert pd["p.registerTime"].tolist() == [
62
+ Timestamp("2011-08-20 11:25:30"),
63
+ Timestamp("2008-11-03 15:25:30.000526"),
64
+ Timestamp("1911-08-20 02:32:21"),
65
+ Timestamp("2031-11-30 12:25:30"),
66
+ Timestamp("1976-12-23 11:21:42"),
67
+ Timestamp("1972-07-31 13:22:30.678559"),
68
+ Timestamp("1976-12-23 04:41:42"),
69
+ Timestamp("2023-02-21 13:25:30"),
70
+ ]
71
+ assert str(pd["p.registerTime"].dtype) == "datetime64[us]"
72
+ assert pd["p.lastJobDuration"].tolist() == [
73
+ Timedelta("1082 days 13:02:00"),
74
+ Timedelta("3750 days 13:00:00.000024"),
75
+ Timedelta("2 days 00:24:11"),
76
+ Timedelta("3750 days 13:00:00.000024"),
77
+ Timedelta("2 days 00:24:11"),
78
+ Timedelta("0 days 00:18:00.024000"),
79
+ Timedelta("3750 days 13:00:00.000024"),
80
+ Timedelta("1082 days 13:02:00"),
81
+ ]
82
+ assert str(pd["p.lastJobDuration"].dtype) == "timedelta64[ns]"
83
+ assert pd["p.workedHours"].tolist() == [
84
+ [10, 5],
85
+ [12, 8],
86
+ [4, 5],
87
+ [1, 9],
88
+ [2],
89
+ [3, 4, 5, 6, 7],
90
+ [1],
91
+ [10, 11, 12, 3, 4, 5, 6, 7],
92
+ ]
93
+ assert str(pd["p.workedHours"].dtype) == "object"
94
+ assert pd["p.usedNames"].tolist() == [
95
+ ["Aida"],
96
+ ["Bobby"],
97
+ ["Carmen", "Fred"],
98
+ ["Wolfeschlegelstein", "Daniel"],
99
+ ["Ein"],
100
+ ["Fesdwe"],
101
+ ["Grad"],
102
+ ["Ad", "De", "Hi", "Kye", "Orlan"],
103
+ ]
104
+ assert str(pd["p.usedNames"].dtype) == "object"
105
+ assert pd["p.courseScoresPerTerm"].tolist() == [
106
+ [[10, 8], [6, 7, 8]],
107
+ [[8, 9], [9, 10]],
108
+ [[8, 10]],
109
+ [[7, 4], [8, 8], [9]],
110
+ [[6], [7], [8]],
111
+ [[8]],
112
+ [[10]],
113
+ [[7], [10], [6, 7]],
114
+ ]
115
+ assert str(pd["p.courseScoresPerTerm"].dtype) == "object"
116
+ assert pd["p.grades"].tolist() == [
117
+ [96, 54, 86, 92],
118
+ [98, 42, 93, 88],
119
+ [91, 75, 21, 95],
120
+ [76, 88, 99, 89],
121
+ [96, 59, 65, 88],
122
+ [80, 78, 34, 83],
123
+ [43, 83, 67, 43],
124
+ [77, 64, 100, 54],
125
+ ]
126
+ assert str(pd["p.grades"].dtype) == "object"
127
+ expected_values = [1.731, 0.99, 1.00, 1.30, 1.463, 1.51, 1.6, 1.323]
128
+ actual_values = pd["p.height"].tolist()
129
+ for expected, actual in zip(expected_values, actual_values):
130
+ assert math.isclose(actual, expected, rel_tol=1e-5)
131
+ assert str(pd["p.height"].dtype) == "float32"
132
+
133
+ def _test_study_at_to_df(conn: lb.Connection) -> None:
134
+ query = "MATCH (p:person)-[r:studyAt]->(o:organisation) return r.* order by r.length;"
135
+ pd = conn.execute(query).get_as_df()
136
+ assert pd["r.year"].tolist() == [2021, 2020, 2020]
137
+ assert str(pd["r.year"].dtype) == "int64"
138
+ assert pd["r.places"].tolist() == [
139
+ ["wwAewsdndweusd", "wek"],
140
+ ["awndsnjwejwen", "isuhuwennjnuhuhuwewe"],
141
+ ["anew", "jsdnwusklklklwewsd"],
142
+ ]
143
+ assert str(pd["r.places"].dtype) == "object"
144
+ assert pd["r.length"].tolist() == [5, 22, 55]
145
+ assert str(pd["r.length"].dtype) == "int16"
146
+ assert pd["r.level"].tolist() == [5, 2, 120]
147
+ assert str(pd["r.level"].dtype) == "int8"
148
+ assert pd["r.code"].tolist() == [9223372036854775808, 23, 6689]
149
+ assert str(pd["r.code"].dtype) == "uint64"
150
+ assert pd["r.temperature"].tolist() == [32800, 20, 1]
151
+ assert str(pd["r.temperature"].dtype) == "uint32"
152
+ assert pd["r.ulength"].tolist() == [33768, 180, 90]
153
+ assert str(pd["r.ulength"].dtype) == "uint16"
154
+ assert pd["r.ulevel"].tolist() == [250, 12, 220]
155
+ assert str(pd["r.ulevel"].dtype) == "uint8"
156
+ assert pd["r.hugedata"].tolist() == [
157
+ 1.8446744073709552e27,
158
+ -15.0,
159
+ -1.8446744073709552e21,
160
+ ]
161
+ assert str(pd["r.hugedata"].dtype) == "float64"
162
+
163
+ def _test_timestamps_to_df(conn: lb.Connection) -> None:
164
+ query = (
165
+ 'RETURN cast("2012-01-01 11:12:12.12345", "TIMESTAMP_NS") as A, cast("2012-01-01 11:12:12.12345", '
166
+ '"TIMESTAMP_MS") as B, cast("2012-01-01 11:12:12.12345", "TIMESTAMP_SEC") as C, '
167
+ 'cast("2012-01-01 11:12:12.12345", "TIMESTAMP_TZ") as D'
168
+ )
169
+ pd = conn.execute(query).get_as_df()
170
+ assert pd["A"].tolist() == [Timestamp("2012-01-01 11:12:12.123450")]
171
+ assert pd["B"].tolist() == [Timestamp("2012-01-01 11:12:12.123000")]
172
+ assert pd["C"].tolist() == [Timestamp("2012-01-01 11:12:12")]
173
+ assert pd["D"].tolist() == [Timestamp("2012-01-01 11:12:12.123450")]
174
+
175
+ def _test_movies_to_df(conn: lb.Connection) -> None:
176
+ query = "MATCH (m:movies) return m.* order by m.length;"
177
+ pd = conn.execute(query).get_as_df()
178
+ assert pd["m.length"].tolist() == [126, 298, 2544]
179
+ assert str(pd["m.length"].dtype) == "int32"
180
+ assert pd["m.description"].tolist() == [
181
+ {
182
+ "rating": 5.3,
183
+ "stars": 2,
184
+ "views": 152,
185
+ "release": datetime.datetime(2011, 8, 20, 11, 25, 30),
186
+ "release_ns": datetime.datetime(2011, 8, 20, 11, 25, 30, 123456),
187
+ "release_ms": datetime.datetime(2011, 8, 20, 11, 25, 30, 123000),
188
+ "release_sec": datetime.datetime(2011, 8, 20, 11, 25, 30),
189
+ "release_tz": datetime.datetime(2011, 8, 20, 11, 25, 30, 123456, pytz.UTC),
190
+ "film": datetime.date(2012, 5, 11),
191
+ "u8": 220,
192
+ "u16": 20,
193
+ "u32": 1,
194
+ "u64": 180,
195
+ "hugedata": Decimal("1844674407370955161811111111"),
196
+ },
197
+ {
198
+ "rating": 1223.0,
199
+ "stars": 100,
200
+ "views": 10003,
201
+ "release": datetime.datetime(2011, 2, 11, 16, 44, 22),
202
+ "release_ns": datetime.datetime(2011, 2, 11, 16, 44, 22, 123456),
203
+ "release_ms": datetime.datetime(2011, 2, 11, 16, 44, 22, 123000),
204
+ "release_sec": datetime.datetime(2011, 2, 11, 16, 44, 22),
205
+ "release_tz": datetime.datetime(2011, 2, 11, 16, 44, 22, 123456, pytz.UTC),
206
+ "film": datetime.date(2013, 2, 22),
207
+ "u8": 1,
208
+ "u16": 15,
209
+ "u32": 200,
210
+ "u64": 4,
211
+ "hugedata": Decimal(-15),
212
+ },
213
+ {
214
+ "rating": 7.0,
215
+ "stars": 10,
216
+ "views": 982,
217
+ "release": datetime.datetime(2018, 11, 13, 13, 33, 11),
218
+ "release_ns": datetime.datetime(2018, 11, 13, 13, 33, 11, 123456),
219
+ "release_ms": datetime.datetime(2018, 11, 13, 13, 33, 11, 123000),
220
+ "release_sec": datetime.datetime(2018, 11, 13, 13, 33, 11),
221
+ "release_tz": datetime.datetime(2018, 11, 13, 13, 33, 11, 123456, pytz.UTC),
222
+ "film": datetime.date(2014, 9, 12),
223
+ "u8": 12,
224
+ "u16": 120,
225
+ "u32": 55,
226
+ "u64": 1,
227
+ "hugedata": Decimal(-1844674407370955161511),
228
+ },
229
+ ]
230
+ assert str(pd["m.description"].dtype) == "object"
231
+ assert pd["m.content"].tolist() == [
232
+ b"\xaa\xabinteresting\x0b",
233
+ b"pure ascii characters",
234
+ b"\xab\xcd",
235
+ ]
236
+ assert str(pd["m.content"].dtype) == "object"
237
+ assert pd["m.audience"].tolist() == [
238
+ {"audience1": 52, "audience53": 42},
239
+ {},
240
+ {"audience1": 33},
241
+ ]
242
+ assert str(pd["m.audience"].dtype) == "object"
243
+ assert pd["m.grade"].tolist() == [True, 254.0, 8.989]
244
+ assert str(pd["m.grade"].dtype) == "object"
245
+
246
+ def _test_serial_to_df(conn: lb.Connection) -> None:
247
+ df = conn.execute("MATCH (a:moviesSerial) RETURN a.ID AS id").get_as_df()
248
+ assert len(df) == 3
249
+ assert df["id"].tolist() == [0, 1, 2]
250
+
251
+ _test_person_to_df(conn)
252
+ conn.set_max_threads_for_exec(2)
253
+ _test_study_at_to_df(conn)
254
+ _test_movies_to_df(conn)
255
+ _test_timestamps_to_df(conn)
256
+ _test_serial_to_df(conn)
257
+
258
+
259
+ def test_df_multiple_times(conn_db_readonly: ConnDB) -> None:
260
+ conn, _ = conn_db_readonly
261
+ query = "MATCH (p:person) return p.ID ORDER BY p.ID"
262
+ res = conn.execute(query)
263
+ df = res.get_as_df()
264
+ df_2 = res.get_as_df()
265
+ df_3 = res.get_as_df()
266
+ assert df["p.ID"].tolist() == [0, 2, 3, 5, 7, 8, 9, 10]
267
+ assert df_2["p.ID"].tolist() == [0, 2, 3, 5, 7, 8, 9, 10]
268
+ assert df_3["p.ID"].tolist() == [0, 2, 3, 5, 7, 8, 9, 10]
269
+
270
+
271
+ def test_df_get_node(conn_db_readonly: ConnDB) -> None:
272
+ conn, _ = conn_db_readonly
273
+ query = "MATCH (p:person) return p"
274
+
275
+ res = conn.execute(query)
276
+ df = res.get_as_df()
277
+ p_list = df["p"].tolist()
278
+ assert len(p_list) == 8
279
+
280
+ ground_truth: dict[str, list[Any]] = {
281
+ "ID": [0, 2, 3, 5, 7, 8, 9, 10],
282
+ "fName": [
283
+ "Alice",
284
+ "Bob",
285
+ "Carol",
286
+ "Dan",
287
+ "Elizabeth",
288
+ "Farooq",
289
+ "Greg",
290
+ "Hubert Blaine Wolfeschlegelsteinhausenbergerdorff",
291
+ ],
292
+ "gender": [1, 2, 1, 2, 1, 2, 2, 2],
293
+ "isStudent": [True, True, False, False, False, True, False, False],
294
+ "eyeSight": [5.0, 5.1, 5.0, 4.8, 4.7, 4.5, 4.9, 4.9],
295
+ "birthdate": [
296
+ datetime.date(1900, 1, 1),
297
+ datetime.date(1900, 1, 1),
298
+ datetime.date(1940, 6, 22),
299
+ datetime.date(1950, 7, 23),
300
+ datetime.date(1980, 10, 26),
301
+ datetime.date(1980, 10, 26),
302
+ datetime.date(1980, 10, 26),
303
+ datetime.date(1990, 11, 27),
304
+ ],
305
+ "registerTime": [
306
+ Timestamp("2011-08-20 11:25:30"),
307
+ Timestamp("2008-11-03 15:25:30.000526"),
308
+ Timestamp("1911-08-20 02:32:21"),
309
+ Timestamp("2031-11-30 12:25:30"),
310
+ Timestamp("1976-12-23 11:21:42"),
311
+ Timestamp("1972-07-31 13:22:30.678559"),
312
+ Timestamp("1976-12-23 04:41:42"),
313
+ Timestamp("2023-02-21 13:25:30"),
314
+ ],
315
+ "lastJobDuration": [
316
+ Timedelta("1082 days 13:02:00"),
317
+ Timedelta("3750 days 13:00:00.000024"),
318
+ Timedelta("2 days 00:24:11"),
319
+ Timedelta("3750 days 13:00:00.000024"),
320
+ Timedelta("2 days 00:24:11"),
321
+ Timedelta("0 days 00:18:00.024000"),
322
+ Timedelta("3750 days 13:00:00.000024"),
323
+ Timedelta("1082 days 13:02:00"),
324
+ ],
325
+ "workedHours": [
326
+ [10, 5],
327
+ [12, 8],
328
+ [4, 5],
329
+ [1, 9],
330
+ [2],
331
+ [3, 4, 5, 6, 7],
332
+ [1],
333
+ [10, 11, 12, 3, 4, 5, 6, 7],
334
+ ],
335
+ "usedNames": [
336
+ ["Aida"],
337
+ ["Bobby"],
338
+ ["Carmen", "Fred"],
339
+ ["Wolfeschlegelstein", "Daniel"],
340
+ ["Ein"],
341
+ ["Fesdwe"],
342
+ ["Grad"],
343
+ ["Ad", "De", "Hi", "Kye", "Orlan"],
344
+ ],
345
+ "courseScoresPerTerm": [
346
+ [[10, 8], [6, 7, 8]],
347
+ [[8, 9], [9, 10]],
348
+ [[8, 10]],
349
+ [[7, 4], [8, 8], [9]],
350
+ [[6], [7], [8]],
351
+ [[8]],
352
+ [[10]],
353
+ [[7], [10], [6, 7]],
354
+ ],
355
+ LABEL: [
356
+ "person",
357
+ "person",
358
+ "person",
359
+ "person",
360
+ "person",
361
+ "person",
362
+ "person",
363
+ "person",
364
+ ],
365
+ }
366
+ for i in range(len(p_list)):
367
+ p = p_list[i]
368
+ for key in ground_truth:
369
+ assert p[key] == ground_truth[key][i]
370
+
371
+
372
+ def test_df_get_node_rel(conn_db_readonly: ConnDB) -> None:
373
+ conn, _ = conn_db_readonly
374
+ res = conn.execute("MATCH (p:person)-[r:workAt]->(o:organisation) RETURN p, r, o ORDER BY p.fName")
375
+
376
+ df = res.get_as_df()
377
+ p_list = df["p"].tolist()
378
+ o_list = df["o"].tolist()
379
+
380
+ assert len(p_list) == 3
381
+ assert len(o_list) == 3
382
+
383
+ ground_truth_p: dict[str, list[Any]] = {
384
+ "ID": [3, 5, 7],
385
+ "fName": ["Carol", "Dan", "Elizabeth"],
386
+ "gender": [1, 2, 1],
387
+ "isStudent": [False, False, False],
388
+ "eyeSight": [5.0, 4.8, 4.7],
389
+ "birthdate": [
390
+ datetime.date(1940, 6, 22),
391
+ datetime.date(1950, 7, 23),
392
+ datetime.date(1980, 10, 26),
393
+ ],
394
+ "registerTime": [
395
+ Timestamp("1911-08-20 02:32:21"),
396
+ Timestamp("2031-11-30 12:25:30"),
397
+ Timestamp("1976-12-23 11:21:42"),
398
+ ],
399
+ "lastJobDuration": [
400
+ Timedelta("48 hours 24 minutes 11 seconds"),
401
+ Timedelta("3750 days 13:00:00.000024"),
402
+ Timedelta("2 days 00:24:11"),
403
+ ],
404
+ "workedHours": [[4, 5], [1, 9], [2]],
405
+ "usedNames": [["Carmen", "Fred"], ["Wolfeschlegelstein", "Daniel"], ["Ein"]],
406
+ "courseScoresPerTerm": [[[8, 10]], [[7, 4], [8, 8], [9]], [[6], [7], [8]]],
407
+ LABEL: ["person", "person", "person"],
408
+ }
409
+ for i in range(len(p_list)):
410
+ p = p_list[i]
411
+ for key in ground_truth_p:
412
+ assert p[key] == ground_truth_p[key][i]
413
+
414
+ ground_truth_o: dict[str, list[Any]] = {
415
+ "ID": [4, 6, 6],
416
+ "name": ["CsWork", "DEsWork", "DEsWork"],
417
+ "orgCode": [934, 824, 824],
418
+ "mark": [4.1, 4.1, 4.1],
419
+ "score": [-100, 7, 7],
420
+ "history": [
421
+ "2 years 4 days 10 hours",
422
+ "2 years 4 hours 22 us 34 minutes",
423
+ "2 years 4 hours 22 us 34 minutes",
424
+ ],
425
+ "licenseValidInterval": [
426
+ Timedelta(days=9414),
427
+ Timedelta(days=3, seconds=36000, microseconds=100000),
428
+ Timedelta(days=3, seconds=36000, microseconds=100000),
429
+ ],
430
+ "rating": [0.78, 0.52, 0.52],
431
+ LABEL: ["organisation", "organisation", "organisation"],
432
+ }
433
+ for i in range(len(o_list)):
434
+ o = df["o"][i]
435
+ for key in ground_truth_o:
436
+ assert o[key] == ground_truth_o[key][i]
437
+
438
+ assert df["r"][0]["year"] == 2015
439
+ assert df["r"][1]["year"] == 2010
440
+ assert df["r"][2]["year"] == 2015
441
+
442
+ for i in range(len(df["r"])):
443
+ assert df["r"][i][SRC] == df["p"][i][ID]
444
+ assert df["r"][i][DST] == df["o"][i][ID]
445
+
446
+
447
+ def test_df_get_recursive_join(conn_db_readonly: ConnDB) -> None:
448
+ conn, _ = conn_db_readonly
449
+ res = conn.execute(
450
+ "MATCH (p:person)-[r:knows*1..2 (e, n | WHERE e.comments = ['rnme','m8sihsdnf2990nfiwf'])]-(m:person) WHERE "
451
+ "p.ID = 0 and m.ID = 0 RETURN r"
452
+ ).get_as_df()
453
+ assert res["r"][0] == {
454
+ NODES: [
455
+ {
456
+ "ID": 2,
457
+ ID: {"offset": 1, "table": 0},
458
+ LABEL: "person",
459
+ "age": 30,
460
+ "birthdate": datetime.date(1900, 1, 1),
461
+ "courseScoresPerTerm": [[8, 9], [9, 10]],
462
+ "eyeSight": 5.1,
463
+ "fName": "Bob",
464
+ "gender": 2,
465
+ "grades": [98, 42, 93, 88],
466
+ "height": 0.9900000095367432,
467
+ "u": UUID("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12"),
468
+ "isStudent": True,
469
+ "isWorker": False,
470
+ "lastJobDuration": datetime.timedelta(days=3750, seconds=46800, microseconds=24),
471
+ "registerTime": datetime.datetime(2008, 11, 3, 15, 25, 30, 526),
472
+ "usedNames": ["Bobby"],
473
+ "workedHours": [12, 8],
474
+ }
475
+ ],
476
+ RELS: [
477
+ {
478
+ ID: {
479
+ "offset": 0,
480
+ "table": 3,
481
+ },
482
+ DST: {"offset": 1, "table": 0},
483
+ LABEL: "knows",
484
+ SRC: {"offset": 0, "table": 0},
485
+ "comments": ["rnme", "m8sihsdnf2990nfiwf"],
486
+ "date": datetime.date(2021, 6, 30),
487
+ "meetTime": datetime.datetime(1986, 10, 21, 21, 8, 31, 521000),
488
+ "notes": 1,
489
+ "summary": {
490
+ "locations": ["'toronto'", "'waterloo'"],
491
+ "transfer": {
492
+ "amount": [100, 200],
493
+ "day": datetime.date(2021, 1, 2),
494
+ },
495
+ },
496
+ "someMap": {"a": "b"},
497
+ "validInterval": datetime.timedelta(days=3750, seconds=46800, microseconds=24),
498
+ },
499
+ {
500
+ ID: {
501
+ "offset": 0,
502
+ "table": 3,
503
+ },
504
+ DST: {"offset": 1, "table": 0},
505
+ LABEL: "knows",
506
+ SRC: {"offset": 0, "table": 0},
507
+ "comments": ["rnme", "m8sihsdnf2990nfiwf"],
508
+ "date": datetime.date(2021, 6, 30),
509
+ "meetTime": datetime.datetime(1986, 10, 21, 21, 8, 31, 521000),
510
+ "notes": 1,
511
+ "summary": {
512
+ "locations": ["'toronto'", "'waterloo'"],
513
+ "transfer": {
514
+ "amount": [100, 200],
515
+ "day": datetime.date(2021, 1, 2),
516
+ },
517
+ },
518
+ "someMap": {"a": "b"},
519
+ "validInterval": datetime.timedelta(days=3750, seconds=46800, microseconds=24),
520
+ },
521
+ ],
522
+ }
523
+
524
+
525
+ def test_get_df_unicode(conn_db_readonly: ConnDB) -> None:
526
+ conn, _ = conn_db_readonly
527
+ res = conn.execute("MATCH (m:movies) RETURN m.name").get_as_df()
528
+ assert res["m.name"].tolist() == [
529
+ "Sóló cón tu párejâ",
530
+ "The 😂😃🧘🏻‍♂️🌍🌦️🍞🚗 movie",
531
+ "Roma",
532
+ ]
533
+
534
+
535
+ def test_get_df_decimal(conn_db_readonly: ConnDB) -> None:
536
+ conn, _ = conn_db_readonly
537
+ res = conn.execute(
538
+ "UNWIND [1, 2, 3] AS A UNWIND [5.7, 8.3, 2.9] AS B RETURN CAST(CAST(A AS DECIMAL) * CAST(B AS DECIMAL) AS DECIMAL(18, 1)) AS PROD"
539
+ ).get_as_df()
540
+ assert sorted(res["PROD"].tolist()) == sorted([
541
+ Decimal("5.7"),
542
+ Decimal("8.3"),
543
+ Decimal("2.9"),
544
+ Decimal("11.4"),
545
+ Decimal("16.6"),
546
+ Decimal("5.8"),
547
+ Decimal("17.1"),
548
+ Decimal("24.9"),
549
+ Decimal("8.7"),
550
+ ])
551
+ res = conn.execute(
552
+ "UNWIND [1, 2, 3] AS A UNWIND [5.7, 8.3, 2.9] AS B RETURN CAST(CAST(A AS DECIMAL) * CAST(B AS DECIMAL) AS DECIMAL(4, 1)) AS PROD"
553
+ ).get_as_df()
554
+ assert sorted(res["PROD"].tolist()) == sorted([
555
+ Decimal("5.7"),
556
+ Decimal("8.3"),
557
+ Decimal("2.9"),
558
+ Decimal("11.4"),
559
+ Decimal("16.6"),
560
+ Decimal("5.8"),
561
+ Decimal("17.1"),
562
+ Decimal("24.9"),
563
+ Decimal("8.7"),
564
+ ])
@@ -0,0 +1,112 @@
1
+ from __future__ import annotations
2
+
3
+ import real_ladybug as lb
4
+
5
+ from type_aliases import ConnDB
6
+
7
+
8
+ def test_get_next(conn_db_in_mem: ConnDB) -> None:
9
+ conn, _ = conn_db_in_mem
10
+ conn.execute("CREATE NODE TABLE person(name STRING, age INT64, PRIMARY KEY(name));")
11
+ conn.execute("CREATE (:person {name: 'Alice', age: 30});")
12
+ conn.execute("CREATE (:person {name: 'Bob', age: 40});")
13
+
14
+ result = conn.execute("MATCH (p:person) RETURN p.*")
15
+ assert result.get_num_tuples() == 2
16
+ result.rows_as_dict()
17
+
18
+ row = result.get_next()
19
+ assert row == {"p.name": "Alice", "p.age": 30}
20
+ row = result.get_next()
21
+ assert row == {"p.name": "Bob", "p.age": 40}
22
+
23
+
24
+ def test_get_all(conn_db_in_mem: ConnDB) -> None:
25
+ conn, _ = conn_db_in_mem
26
+ conn.execute("CREATE NODE TABLE person(name STRING, age INT64, PRIMARY KEY(name));")
27
+ conn.execute("CREATE (:person {name: 'Alice', age: 30});")
28
+ conn.execute("CREATE (:person {name: 'Bob', age: 40});")
29
+
30
+ result = conn.execute("MATCH (p:person) RETURN p.*")
31
+ assert result.get_num_tuples() == 2
32
+ result.rows_as_dict()
33
+
34
+ rows = result.get_all()
35
+ assert rows[0] == {"p.name": "Alice", "p.age": 30}
36
+ assert rows[1] == {"p.name": "Bob", "p.age": 40}
37
+
38
+
39
+ def test_get_n(conn_db_in_mem: ConnDB) -> None:
40
+ conn, _ = conn_db_in_mem
41
+ conn.execute("CREATE NODE TABLE person(name STRING, age INT64, PRIMARY KEY(name));")
42
+ conn.execute("CREATE (:person {name: 'Alice', age: 30});")
43
+ conn.execute("CREATE (:person {name: 'Bob', age: 40});")
44
+ conn.execute("CREATE (:person {name: 'Cole', age: 20});")
45
+
46
+ result = conn.execute("MATCH (p:person) RETURN p.*")
47
+ assert result.get_num_tuples() == 3
48
+ result.rows_as_dict()
49
+
50
+ rows = result.get_n(2)
51
+
52
+ assert len(rows) == 2
53
+ assert rows[0] == {"p.name": "Alice", "p.age": 30}
54
+ assert rows[1] == {"p.name": "Bob", "p.age": 40}
55
+
56
+ rows = result.get_n(1)
57
+
58
+ assert len(rows) == 1
59
+ assert rows[0] == {"p.name": "Cole", "p.age": 20}
60
+
61
+ rows = result.get_n(1)
62
+
63
+ assert len(rows) == 0
64
+
65
+
66
+ def test_dict_iteration(conn_db_in_mem: ConnDB) -> None:
67
+ conn, _ = conn_db_in_mem
68
+ conn.execute("CREATE NODE TABLE person(name STRING, age INT64, PRIMARY KEY(name));")
69
+ conn.execute("CREATE (:person {name: 'Alice', age: 30});")
70
+ conn.execute("CREATE (:person {name: 'Bob', age: 40});")
71
+ result = conn.execute("MATCH (p:person) RETURN p.*")
72
+ assert result.get_num_tuples() == 2
73
+
74
+ result.rows_as_dict()
75
+ rows = list(result)
76
+ assert rows[0] == {"p.name": "Alice", "p.age": 30}
77
+ assert rows[1] == {"p.name": "Bob", "p.age": 40}
78
+
79
+
80
+ def test_dict_iteration_inline(conn_db_in_mem: ConnDB) -> None:
81
+ conn, _ = conn_db_in_mem
82
+ conn.execute("CREATE NODE TABLE person(name STRING, age INT64, PRIMARY KEY(name));")
83
+ conn.execute("CREATE (:person {name: 'Alice', age: 30});")
84
+ conn.execute("CREATE (:person {name: 'Bob', age: 40});")
85
+ result = conn.execute("MATCH (p:person) RETURN p.*")
86
+ assert result.get_num_tuples() == 2
87
+
88
+ rows = list(result.rows_as_dict())
89
+ assert rows[0] == {"p.name": "Alice", "p.age": 30}
90
+ assert rows[1] == {"p.name": "Bob", "p.age": 40}
91
+
92
+
93
+ def test_on_off(conn_db_in_mem: ConnDB) -> None:
94
+ conn, _ = conn_db_in_mem
95
+ conn.execute("CREATE NODE TABLE person(name STRING, age INT64, PRIMARY KEY(name));")
96
+ conn.execute("CREATE (:person {name: 'Alice', age: 30});")
97
+ conn.execute("CREATE (:person {name: 'Bob', age: 40});")
98
+ conn.execute("CREATE (:person {name: 'Cole', age: 20});")
99
+
100
+ result = conn.execute("MATCH (p:person) RETURN p.*")
101
+ assert result.get_num_tuples() == 3
102
+
103
+ row = result.get_next()
104
+ assert row == ["Alice", 30]
105
+
106
+ result.rows_as_dict()
107
+ row = result.get_next()
108
+ assert row == {"p.name": "Bob", "p.age": 40}
109
+
110
+ result.rows_as_dict(False)
111
+ row = result.get_next()
112
+ assert row == ["Cole", 20]