flow.record 3.22.dev5__tar.gz → 3.22.dev6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/PKG-INFO +1 -1
  2. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/sqlite.py +5 -0
  3. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/version.py +3 -3
  4. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow.record.egg-info/PKG-INFO +1 -1
  5. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_sqlite_duckdb.py +13 -8
  6. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/.git-blame-ignore-revs +0 -0
  7. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/.gitattributes +0 -0
  8. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/COPYRIGHT +0 -0
  9. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/LICENSE +0 -0
  10. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/MANIFEST.in +0 -0
  11. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/README.md +0 -0
  12. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/examples/__init__.py +0 -0
  13. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/examples/filesystem.py +0 -0
  14. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/examples/passivedns.py +0 -0
  15. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/examples/records.json +0 -0
  16. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/examples/selectors.py +0 -0
  17. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/examples/tcpconn.py +0 -0
  18. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/__init__.py +0 -0
  19. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/__init__.py +0 -0
  20. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/archive.py +0 -0
  21. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/avro.py +0 -0
  22. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/broker.py +0 -0
  23. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/csvfile.py +0 -0
  24. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/duckdb.py +0 -0
  25. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/elastic.py +0 -0
  26. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/jsonfile.py +0 -0
  27. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/line.py +0 -0
  28. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/mongo.py +0 -0
  29. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/split.py +0 -0
  30. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/splunk.py +0 -0
  31. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/stream.py +0 -0
  32. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/text.py +0 -0
  33. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/adapter/xlsx.py +0 -0
  34. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/base.py +0 -0
  35. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/context.py +0 -0
  36. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/exceptions.py +0 -0
  37. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/__init__.py +0 -0
  38. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/credential.py +0 -0
  39. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/net/__init__.py +0 -0
  40. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/net/ip.py +0 -0
  41. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/net/ipv4.py +0 -0
  42. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/net/tcp.py +0 -0
  43. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/fieldtypes/net/udp.py +0 -0
  44. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/jsonpacker.py +0 -0
  45. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/packer.py +0 -0
  46. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/selector.py +0 -0
  47. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/stream.py +0 -0
  48. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/tools/__init__.py +0 -0
  49. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/tools/geoip.py +0 -0
  50. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/tools/rdump.py +0 -0
  51. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/utils.py +0 -0
  52. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow/record/whitelist.py +0 -0
  53. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow.record.egg-info/SOURCES.txt +0 -0
  54. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow.record.egg-info/dependency_links.txt +0 -0
  55. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow.record.egg-info/entry_points.txt +0 -0
  56. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow.record.egg-info/requires.txt +0 -0
  57. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/flow.record.egg-info/top_level.txt +0 -0
  58. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/pyproject.toml +0 -0
  59. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/setup.cfg +0 -0
  60. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/__init__.py +0 -0
  61. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/_data/.gitkeep +0 -0
  62. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/_docs/Makefile +0 -0
  63. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/_docs/conf.py +0 -0
  64. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/_docs/index.rst +0 -0
  65. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/_utils.py +0 -0
  66. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/__init__.py +0 -0
  67. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_avro.py +0 -0
  68. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_csv.py +0 -0
  69. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_elastic.py +0 -0
  70. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_json.py +0 -0
  71. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_line.py +0 -0
  72. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_splunk.py +0 -0
  73. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_text.py +0 -0
  74. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/adapter/test_xlsx.py +0 -0
  75. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/conftest.py +0 -0
  76. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/fieldtypes/__init__.py +0 -0
  77. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/fieldtypes/test_boolean.py +0 -0
  78. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/fieldtypes/test_fieldtypes.py +0 -0
  79. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/fieldtypes/test_ip.py +0 -0
  80. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/packer/__init__.py +0 -0
  81. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/packer/test_json_packer.py +0 -0
  82. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/packer/test_packer.py +0 -0
  83. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/record/__init__.py +0 -0
  84. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/record/test_adapter.py +0 -0
  85. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/record/test_context.py +0 -0
  86. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/record/test_descriptor.py +0 -0
  87. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/record/test_multi_timestamp.py +0 -0
  88. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/record/test_record.py +0 -0
  89. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/selector/__init__.py +0 -0
  90. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/selector/test_compiled.py +0 -0
  91. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/selector/test_selectors.py +0 -0
  92. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/test_deprecations.py +0 -0
  93. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/test_regressions.py +0 -0
  94. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/test_utils.py +0 -0
  95. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/tools/__init__.py +0 -0
  96. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tests/tools/test_rdump.py +0 -0
  97. {flow_record-3.22.dev5 → flow_record-3.22.dev6}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flow.record
3
- Version: 3.22.dev5
3
+ Version: 3.22.dev6
4
4
  Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -204,6 +204,11 @@ class SqliteReader(AbstractReader):
204
204
  if match_record_with_context(record, selector, ctx):
205
205
  yield record
206
206
 
207
+ def close(self) -> None:
208
+ if self.con:
209
+ self.con.close()
210
+ self.con = None
211
+
207
212
 
208
213
  class SqliteWriter(AbstractWriter):
209
214
  """SQLite writer."""
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '3.22.dev5'
32
- __version_tuple__ = version_tuple = (3, 22, 'dev5')
31
+ __version__ = version = '3.22.dev6'
32
+ __version_tuple__ = version_tuple = (3, 22, 'dev6')
33
33
 
34
- __commit_id__ = commit_id = 'gc3f8cd8c6'
34
+ __commit_id__ = commit_id = 'g668138538'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flow.record
3
- Version: 3.22.dev5
3
+ Version: 3.22.dev6
4
4
  Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import sqlite3
4
+ from contextlib import closing
4
5
  from datetime import datetime, timezone
5
6
  from typing import TYPE_CHECKING, Any, NamedTuple
6
7
 
@@ -136,7 +137,7 @@ def test_write_to_sqlite(tmp_path: Path, count: int, db: Database) -> None:
136
137
  writer.write(record)
137
138
 
138
139
  record_count = 0
139
- with db.connector.connect(str(db_path)) as con:
140
+ with closing(db.connector.connect(str(db_path))) as con:
140
141
  cursor = con.execute("SELECT COUNT(*) FROM 'test/record'")
141
142
  record_count = cursor.fetchone()[0]
142
143
 
@@ -157,7 +158,7 @@ def test_read_from_sqlite(tmp_path: Path, db: Database) -> None:
157
158
  """Tests basic reading from a SQLite database."""
158
159
  # Generate a SQLite database
159
160
  db_path = tmp_path / "records.db"
160
- with db.connector.connect(str(db_path)) as con:
161
+ with closing(db.connector.connect(str(db_path))) as con:
161
162
  con.execute(
162
163
  """
163
164
  CREATE TABLE 'test/record' (
@@ -176,6 +177,7 @@ def test_read_from_sqlite(tmp_path: Path, db: Database) -> None:
176
177
  """,
177
178
  (f"record{i}", f"foobar{i}".encode(), dt_isoformat, 3.14 + i),
178
179
  )
180
+ con.commit()
179
181
 
180
182
  # Read the SQLite database using flow.record
181
183
  with RecordReader(f"{db.scheme}://{db_path}") as reader:
@@ -251,7 +253,7 @@ def test_write_zero_records(tmp_path: Path, db: Database) -> None:
251
253
  assert writer
252
254
 
253
255
  # test if it's a valid database
254
- with db.connector.connect(str(db_path)) as con:
256
+ with closing(db.connector.connect(str(db_path))) as con:
255
257
  assert con.execute("SELECT * FROM sqlite_master").fetchall() == []
256
258
 
257
259
 
@@ -272,9 +274,10 @@ def test_write_zero_records(tmp_path: Path, db: Database) -> None:
272
274
  def test_non_strict_sqlite_fields(tmp_path: Path, sqlite_coltype: str, sqlite_value: Any, expected_value: Any) -> None:
273
275
  """SQLite by default is non strict, meaning that the value could be of different type than the column type."""
274
276
  db = tmp_path / "records.db"
275
- with sqlite3.connect(db) as con:
277
+ with closing(sqlite3.connect(db)) as con:
276
278
  con.execute(f"CREATE TABLE 'strict-test' (field {sqlite_coltype})")
277
279
  con.execute("INSERT INTO 'strict-test' VALUES(?)", (sqlite_value,))
280
+ con.commit()
278
281
 
279
282
  with RecordReader(f"sqlite://{db}") as reader:
280
283
  record = next(iter(reader))
@@ -294,10 +297,11 @@ def test_invalid_table_names_quoting(tmp_path: Path, invalid_table_name: str) ->
294
297
 
295
298
  # Creating the tables with these invalid_table_names in SQLite is no problem
296
299
  db = tmp_path / "records.db"
297
- with sqlite3.connect(db) as con:
300
+ with closing(sqlite3.connect(db)) as con:
298
301
  con.execute(f"CREATE TABLE [{invalid_table_name}] (field TEXT, field2 TEXT)")
299
302
  con.execute(f"INSERT INTO [{invalid_table_name}] VALUES(?, ?)", ("hello", "world"))
300
303
  con.execute(f"INSERT INTO [{invalid_table_name}] VALUES(?, ?)", ("goodbye", "planet"))
304
+ con.commit()
301
305
 
302
306
  # However, these invalid_table_names should raise an exception when reading
303
307
  with (
@@ -320,10 +324,11 @@ def test_invalid_field_names_quoting(tmp_path: Path, invalid_field_name: str) ->
320
324
 
321
325
  # Creating the table with invalid field name in SQLite is no problem
322
326
  db = tmp_path / "records.db"
323
- with sqlite3.connect(db) as con:
327
+ with closing(sqlite3.connect(db)) as con:
324
328
  con.execute(f"CREATE TABLE [test] (field TEXT, [{invalid_field_name}] TEXT)")
325
329
  con.execute("INSERT INTO [test] VALUES(?, ?)", ("hello", "world"))
326
330
  con.execute("INSERT INTO [test] VALUES(?, ?)", ("goodbye", "planet"))
331
+ con.commit()
327
332
 
328
333
  # However, these field names are invalid in flow.record and should raise an exception
329
334
  with (
@@ -365,7 +370,7 @@ def test_batch_size(
365
370
  writer.write(next(records))
366
371
 
367
372
  # test count of records in table (no flush yet if batch_size > 1)
368
- with db.connector.connect(str(db_path)) as con:
373
+ with closing(db.connector.connect(str(db_path))) as con:
369
374
  x = con.execute('SELECT COUNT(*) FROM "test/record"')
370
375
  assert x.fetchone()[0] is expected_first
371
376
 
@@ -374,7 +379,7 @@ def test_batch_size(
374
379
  writer.write(next(records))
375
380
 
376
381
  # test count of records in table after flush
377
- with db.connector.connect(str(db_path)) as con:
382
+ with closing(db.connector.connect(str(db_path))) as con:
378
383
  x = con.execute('SELECT COUNT(*) FROM "test/record"')
379
384
  assert x.fetchone()[0] == expected_second
380
385
 
File without changes
File without changes