nanasqlite 1.4.1.dev2__tar.gz → 1.5.0.dev2__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 (67) hide show
  1. nanasqlite-1.5.0.dev2/MANIFEST.in +2 -0
  2. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/PKG-INFO +65 -3
  3. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/README.md +64 -2
  4. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/pyproject.toml +7 -3
  5. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/__init__.py +14 -2
  6. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/async_core.py +227 -97
  7. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/cache.py +11 -11
  8. nanasqlite-1.5.0.dev2/src/nanasqlite/compat.py +44 -0
  9. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/core.py +538 -253
  10. nanasqlite-1.5.0.dev2/src/nanasqlite/hooks.py +211 -0
  11. nanasqlite-1.5.0.dev2/src/nanasqlite/protocols.py +21 -0
  12. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/sql_utils.py +2 -0
  13. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/utils.py +48 -14
  14. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/v2_engine.py +243 -135
  15. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2/src}/nanasqlite.egg-info/PKG-INFO +65 -3
  16. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2/src}/nanasqlite.egg-info/SOURCES.txt +14 -5
  17. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_async.py +18 -0
  18. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_async_benchmark.py +98 -49
  19. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_async_cache.py +4 -3
  20. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_audit_poc.py +62 -2
  21. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_benchmark.py +40 -12
  22. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_encryption.py +11 -4
  23. nanasqlite-1.5.0.dev2/tests/test_hooks.py +103 -0
  24. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_nanasqlite.py +18 -0
  25. nanasqlite-1.5.0.dev2/tests/test_sec02_redos.py +32 -0
  26. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_table_inheritance_comprehensive.py +15 -11
  27. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_10.py +3 -3
  28. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_2.py +14 -6
  29. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_3.py +2 -4
  30. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_4.py +15 -10
  31. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_5.py +5 -15
  32. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_6.py +1 -3
  33. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_7.py +12 -19
  34. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_8.py +6 -20
  35. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_review_fixes.py +1 -0
  36. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_utils_expiring_dict.py +11 -2
  37. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_v130_features.py +5 -1
  38. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_v134b1_features.py +6 -5
  39. nanasqlite-1.5.0.dev2/tests/test_v150dev1_audit_fixes.py +304 -0
  40. nanasqlite-1.5.0.dev2/tests/test_v1_4_1_audit_fixes.py +253 -0
  41. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_v2_engine.py +1 -0
  42. nanasqlite-1.5.0.dev2/tests/test_v2_resource_management.py +78 -0
  43. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_validkit_integration.py +27 -18
  44. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/LICENSE +0 -0
  45. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/setup.cfg +0 -0
  46. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/exceptions.py +0 -0
  47. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/src/nanasqlite/py.typed +0 -0
  48. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2/src}/nanasqlite.egg-info/dependency_links.txt +0 -0
  49. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2/src}/nanasqlite.egg-info/requires.txt +0 -0
  50. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2/src}/nanasqlite.egg-info/top_level.txt +0 -0
  51. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_additional_features.py +0 -0
  52. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_aliases_v120.py +0 -0
  53. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_async_fixes_v120.py +0 -0
  54. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_async_pool.py +0 -0
  55. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_cache.py +0 -0
  56. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_concurrent_table_writes.py +0 -0
  57. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_docs_validation_guide.py +0 -0
  58. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_edge_cases_v120.py +0 -0
  59. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_enhancements.py +0 -0
  60. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_json_backends.py +0 -0
  61. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_new_features.py +0 -0
  62. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_security.py +0 -0
  63. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_security_additions.py +0 -0
  64. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_security_async_v120.py +0 -0
  65. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_security_v120.py +0 -0
  66. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_sql_utils.py +0 -0
  67. {nanasqlite-1.4.1.dev2 → nanasqlite-1.5.0.dev2}/tests/test_tdd_cycle_9.py +0 -0
@@ -0,0 +1,2 @@
1
+ include src/nanasqlite/py.typed
2
+ recursive-include src/nanasqlite *.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nanasqlite
3
- Version: 1.4.1.dev2
3
+ Version: 1.5.0.dev2
4
4
  Summary: A dict-like SQLite wrapper with APSW for instant persistence and memory caching
5
5
  Author-email: Disnana <support@disnana.com>
6
6
  License-Expression: MIT
@@ -145,15 +145,43 @@ with NanaSQLite("mydata.db") as db:
145
145
  - [Benchmark Trends 📊](https://nanasqlite.disnana.com/dev/bench/)
146
146
  - [Migration Guide (v1.1.x to v1.2.0)](MIGRATION_GUIDE.md)
147
147
 
148
- ### ✨ v1.4.x New Features (v2 Architecture)
148
+ ### ✨ v1.5.x New Features (Ultimate Hooks)
149
+
150
+ **Ultimate Hooks: Flexible Validation & External Constraints**
151
+ Intercept database operations with custom hooks or built-in constraints. Easily validate data, enforce uniqueness, check foreign keys, or flawlessly integrate with Pydantic.
152
+
153
+ ```python
154
+ from nanasqlite import NanaSQLite
155
+ from nanasqlite.hooks import UniqueHook, CheckHook, PydanticHook
156
+ from pydantic import BaseModel
157
+
158
+ class UserConfig(BaseModel):
159
+ version: int
160
+ theme: str
161
+
162
+ db = NanaSQLite("config.db")
163
+ db.add_hook(UniqueHook("email"))
164
+ db.add_hook(CheckHook(lambda k, v: v.get("age", 0) >= 18, "Age must be >= 18"))
165
+ db.add_hook(PydanticHook(UserConfig))
166
+
167
+ # Write a dict, reads back as a Pydantic Model automatically!
168
+ db["user_conf"] = {"version": 1, "theme": "dark", "email": "test@example.com", "age": 20}
169
+ config = db["user_conf"]
170
+ print(config.theme) # 'dark'
171
+ ```
149
172
 
150
- **v2 Architecture: Non-blocking Background Persistance**
173
+ ### v1.4.x New Features (v2 Architecture)
151
174
  Introduced an optional "Write-Back Cache" architecture where all KVS writes are instantly available in memory but saved to SQLite asynchronously in the background. Read latency remains exactly zero.
152
175
 
153
176
  ```python
154
177
  # Enable v2 mode with automatic background flushing
155
178
  db = NanaSQLite("high_load.db", v2_mode=True, flush_mode="time", flush_interval=1.0)
156
179
 
180
+ # Optional: Use V2Config for cleaner initialization (v1.4.1+)
181
+ from nanasqlite import V2Config
182
+ cfg = V2Config(flush_mode="time", flush_interval=5.0, enable_metrics=True)
183
+ db = NanaSQLite("mydata.db", v2_mode=True, v2_config=cfg)
184
+
157
185
  # The main thread is NEVER blocked by disk I/O!
158
186
  db["heavy_key"] = validate_and_compute_data()
159
187
  ```
@@ -169,6 +197,8 @@ db["heavy_key"] = validate_and_compute_data()
169
197
  - **Backup & Restore** (v1.3.4b1): Online backup via APSW's SQLite backup API and one-call restore from any backup file.
170
198
  - **Security Audit & Hardening** (v1.3.4): Whitelist-based column type validation, AEAD nonce validation, closed-instance safety on all dict methods. See [CHANGELOG](CHANGELOG.md) for full details.
171
199
  - **Security Audit & v2 Bug Fixes** (v1.4.0): Fixed SQL injection in `create_table()` column types, V2Engine callback ordering, async child attribute inheritance, and v2 mode read-query bypass. See [CHANGELOG](CHANGELOG.md) for full details.
200
+ - **Critical Bug Fix** (v1.4.1): Fixed `AttributeError` in `upsert()` / `aupsert()` when using specific call patterns with `conflict_columns`. Added negative caching for LRU/TTL to improve performance.
201
+ - **Refactoring & Quality** (v1.4.1): Introduced `V2Config` to group engine parameters and resolve SonarCloud warnings. Improved Docker CI robustness. See [CHANGELOG](CHANGELOG.md) for full details.
172
202
 
173
203
  ```python
174
204
  # Lock Timeout
@@ -344,6 +374,31 @@ with NanaSQLite("mydata.db") as db:
344
374
  - [ベンチマーク履歴 📊](https://nanasqlite.disnana.com/dev/bench/)
345
375
  - [移行ガイド (v1.1.x から v1.2.0)](MIGRATION_GUIDE.md)
346
376
 
377
+ ### ✨ v1.5.x 新機能 (Ultimate Hooks)
378
+
379
+ **Ultimate Hooks: 柔軟なバリデーションと外部制約アーキテクチャ**
380
+ データベースの読み書き・削除をカスタムフックや組み込み制約でインターセプトできます。データの検証、一意性の保証、外部キー制約のチェック、Pydantic とのシームレスな統合などが容易に行えます。
381
+
382
+ ```python
383
+ from nanasqlite import NanaSQLite
384
+ from nanasqlite.hooks import UniqueHook, CheckHook, PydanticHook
385
+ from pydantic import BaseModel
386
+
387
+ class UserConfig(BaseModel):
388
+ version: int
389
+ theme: str
390
+
391
+ db = NanaSQLite("config.db")
392
+ db.add_hook(UniqueHook("email"))
393
+ db.add_hook(CheckHook(lambda k, v: v.get("age", 0) >= 18, "Age must be >= 18"))
394
+ db.add_hook(PydanticHook(UserConfig))
395
+
396
+ # dict を書き込むと、自動的に検証され Pydantic モデルとして読み出せます!
397
+ db["user_conf"] = {"version": 1, "theme": "dark", "email": "test@example.com", "age": 20}
398
+ config = db["user_conf"]
399
+ print(config.theme) # 'dark'
400
+ ```
401
+
347
402
  ### ✨ v1.4.x 新機能 (v2 アーキテクチャ)
348
403
 
349
404
  **v2 アーキテクチャ: ノンブロッキング・バックグラウンド永続化**
@@ -353,6 +408,11 @@ KVSの書き込みをすべて「Write-Back Cache(メモリ優先更新)」
353
408
  # v2モードを有効化(1秒ごとのバックグラウンドフラッシュ)
354
409
  db = NanaSQLite("high_load.db", v2_mode=True, flush_mode="time", flush_interval=1.0)
355
410
 
411
+ # オプション: V2Configを使用して設定をひとまとめに(v1.4.1+)
412
+ from nanasqlite import V2Config
413
+ cfg = V2Config(flush_mode="time", flush_interval=5.0, enable_metrics=True)
414
+ db = NanaSQLite("mydata.db", v2_mode=True, v2_config=cfg)
415
+
356
416
  # どんなに重いI/Oが発生しても、メインスレッドは一切ブロックされません!
357
417
  db["heavy_key"] = validate_and_compute_data()
358
418
  ```
@@ -368,6 +428,8 @@ db["heavy_key"] = validate_and_compute_data()
368
428
  - **バックアップ / リストア** (v1.3.4b1): APSW の SQLite バックアップ API によるオンラインバックアップと、一発でのリストアをサポート。
369
429
  - **セキュリティ監査・強化** (v1.3.4): column_type ホワイトリスト検証、AEAD nonce 検証、全 dict メソッドのクローズ済みインスタンス安全性。詳細は [CHANGELOG](CHANGELOG.md) を参照。
370
430
  - **セキュリティ監査・v2 バグ修正** (v1.4.0): `create_table()` カラム型SQLインジェクション修正、V2Engineコールバック順序修正、非同期子インスタンス属性継承修正、v2モード読み取りクエリバイパス修正。詳細は [CHANGELOG](CHANGELOG.md) を参照。
431
+ - **致命的バグ修正・性能向上** (v1.4.1): `upsert()` / `aupsert()` における `AttributeError` を修正。LRU/TTL キャッシュへのネガティブキャッシュ導入による性能向上。詳細は [CHANGELOG](CHANGELOG.md) を参照。
432
+ - **リファクタリング・品質向上** (v1.4.1): `V2Config` の導入による引数管理の整理と、Docker CI環境の安定化を実施。
371
433
 
372
434
  ```python
373
435
  # ロックタイムアウト
@@ -90,15 +90,43 @@ with NanaSQLite("mydata.db") as db:
90
90
  - [Benchmark Trends 📊](https://nanasqlite.disnana.com/dev/bench/)
91
91
  - [Migration Guide (v1.1.x to v1.2.0)](MIGRATION_GUIDE.md)
92
92
 
93
- ### ✨ v1.4.x New Features (v2 Architecture)
93
+ ### ✨ v1.5.x New Features (Ultimate Hooks)
94
+
95
+ **Ultimate Hooks: Flexible Validation & External Constraints**
96
+ Intercept database operations with custom hooks or built-in constraints. Easily validate data, enforce uniqueness, check foreign keys, or flawlessly integrate with Pydantic.
97
+
98
+ ```python
99
+ from nanasqlite import NanaSQLite
100
+ from nanasqlite.hooks import UniqueHook, CheckHook, PydanticHook
101
+ from pydantic import BaseModel
102
+
103
+ class UserConfig(BaseModel):
104
+ version: int
105
+ theme: str
106
+
107
+ db = NanaSQLite("config.db")
108
+ db.add_hook(UniqueHook("email"))
109
+ db.add_hook(CheckHook(lambda k, v: v.get("age", 0) >= 18, "Age must be >= 18"))
110
+ db.add_hook(PydanticHook(UserConfig))
111
+
112
+ # Write a dict, reads back as a Pydantic Model automatically!
113
+ db["user_conf"] = {"version": 1, "theme": "dark", "email": "test@example.com", "age": 20}
114
+ config = db["user_conf"]
115
+ print(config.theme) # 'dark'
116
+ ```
94
117
 
95
- **v2 Architecture: Non-blocking Background Persistance**
118
+ ### v1.4.x New Features (v2 Architecture)
96
119
  Introduced an optional "Write-Back Cache" architecture where all KVS writes are instantly available in memory but saved to SQLite asynchronously in the background. Read latency remains exactly zero.
97
120
 
98
121
  ```python
99
122
  # Enable v2 mode with automatic background flushing
100
123
  db = NanaSQLite("high_load.db", v2_mode=True, flush_mode="time", flush_interval=1.0)
101
124
 
125
+ # Optional: Use V2Config for cleaner initialization (v1.4.1+)
126
+ from nanasqlite import V2Config
127
+ cfg = V2Config(flush_mode="time", flush_interval=5.0, enable_metrics=True)
128
+ db = NanaSQLite("mydata.db", v2_mode=True, v2_config=cfg)
129
+
102
130
  # The main thread is NEVER blocked by disk I/O!
103
131
  db["heavy_key"] = validate_and_compute_data()
104
132
  ```
@@ -114,6 +142,8 @@ db["heavy_key"] = validate_and_compute_data()
114
142
  - **Backup & Restore** (v1.3.4b1): Online backup via APSW's SQLite backup API and one-call restore from any backup file.
115
143
  - **Security Audit & Hardening** (v1.3.4): Whitelist-based column type validation, AEAD nonce validation, closed-instance safety on all dict methods. See [CHANGELOG](CHANGELOG.md) for full details.
116
144
  - **Security Audit & v2 Bug Fixes** (v1.4.0): Fixed SQL injection in `create_table()` column types, V2Engine callback ordering, async child attribute inheritance, and v2 mode read-query bypass. See [CHANGELOG](CHANGELOG.md) for full details.
145
+ - **Critical Bug Fix** (v1.4.1): Fixed `AttributeError` in `upsert()` / `aupsert()` when using specific call patterns with `conflict_columns`. Added negative caching for LRU/TTL to improve performance.
146
+ - **Refactoring & Quality** (v1.4.1): Introduced `V2Config` to group engine parameters and resolve SonarCloud warnings. Improved Docker CI robustness. See [CHANGELOG](CHANGELOG.md) for full details.
117
147
 
118
148
  ```python
119
149
  # Lock Timeout
@@ -289,6 +319,31 @@ with NanaSQLite("mydata.db") as db:
289
319
  - [ベンチマーク履歴 📊](https://nanasqlite.disnana.com/dev/bench/)
290
320
  - [移行ガイド (v1.1.x から v1.2.0)](MIGRATION_GUIDE.md)
291
321
 
322
+ ### ✨ v1.5.x 新機能 (Ultimate Hooks)
323
+
324
+ **Ultimate Hooks: 柔軟なバリデーションと外部制約アーキテクチャ**
325
+ データベースの読み書き・削除をカスタムフックや組み込み制約でインターセプトできます。データの検証、一意性の保証、外部キー制約のチェック、Pydantic とのシームレスな統合などが容易に行えます。
326
+
327
+ ```python
328
+ from nanasqlite import NanaSQLite
329
+ from nanasqlite.hooks import UniqueHook, CheckHook, PydanticHook
330
+ from pydantic import BaseModel
331
+
332
+ class UserConfig(BaseModel):
333
+ version: int
334
+ theme: str
335
+
336
+ db = NanaSQLite("config.db")
337
+ db.add_hook(UniqueHook("email"))
338
+ db.add_hook(CheckHook(lambda k, v: v.get("age", 0) >= 18, "Age must be >= 18"))
339
+ db.add_hook(PydanticHook(UserConfig))
340
+
341
+ # dict を書き込むと、自動的に検証され Pydantic モデルとして読み出せます!
342
+ db["user_conf"] = {"version": 1, "theme": "dark", "email": "test@example.com", "age": 20}
343
+ config = db["user_conf"]
344
+ print(config.theme) # 'dark'
345
+ ```
346
+
292
347
  ### ✨ v1.4.x 新機能 (v2 アーキテクチャ)
293
348
 
294
349
  **v2 アーキテクチャ: ノンブロッキング・バックグラウンド永続化**
@@ -298,6 +353,11 @@ KVSの書き込みをすべて「Write-Back Cache(メモリ優先更新)」
298
353
  # v2モードを有効化(1秒ごとのバックグラウンドフラッシュ)
299
354
  db = NanaSQLite("high_load.db", v2_mode=True, flush_mode="time", flush_interval=1.0)
300
355
 
356
+ # オプション: V2Configを使用して設定をひとまとめに(v1.4.1+)
357
+ from nanasqlite import V2Config
358
+ cfg = V2Config(flush_mode="time", flush_interval=5.0, enable_metrics=True)
359
+ db = NanaSQLite("mydata.db", v2_mode=True, v2_config=cfg)
360
+
301
361
  # どんなに重いI/Oが発生しても、メインスレッドは一切ブロックされません!
302
362
  db["heavy_key"] = validate_and_compute_data()
303
363
  ```
@@ -313,6 +373,8 @@ db["heavy_key"] = validate_and_compute_data()
313
373
  - **バックアップ / リストア** (v1.3.4b1): APSW の SQLite バックアップ API によるオンラインバックアップと、一発でのリストアをサポート。
314
374
  - **セキュリティ監査・強化** (v1.3.4): column_type ホワイトリスト検証、AEAD nonce 検証、全 dict メソッドのクローズ済みインスタンス安全性。詳細は [CHANGELOG](CHANGELOG.md) を参照。
315
375
  - **セキュリティ監査・v2 バグ修正** (v1.4.0): `create_table()` カラム型SQLインジェクション修正、V2Engineコールバック順序修正、非同期子インスタンス属性継承修正、v2モード読み取りクエリバイパス修正。詳細は [CHANGELOG](CHANGELOG.md) を参照。
376
+ - **致命的バグ修正・性能向上** (v1.4.1): `upsert()` / `aupsert()` における `AttributeError` を修正。LRU/TTL キャッシュへのネガティブキャッシュ導入による性能向上。詳細は [CHANGELOG](CHANGELOG.md) を参照。
377
+ - **リファクタリング・品質向上** (v1.4.1): `V2Config` の導入による引数管理の整理と、Docker CI環境の安定化を実施。
316
378
 
317
379
  ```python
318
380
  # ロックタイムアウト
@@ -84,8 +84,12 @@ Repository = "https://github.com/disnana/nanasqlite"
84
84
  Issues = "https://github.com/disnana/nanasqlite/issues"
85
85
 
86
86
  [tool.setuptools]
87
- packages = ["nanasqlite"]
88
- package-dir = {"nanasqlite" = "src/nanasqlite"}
87
+ include-package-data = true
88
+
89
+ [tool.setuptools.packages.find]
90
+ where = ["src"]
91
+ include = ["nanasqlite*"]
92
+ namespaces = false
89
93
 
90
94
  [tool.setuptools.package-data]
91
95
  nanasqlite = ["py.typed"]
@@ -130,7 +134,7 @@ ignore = [
130
134
  known-first-party = ["nanasqlite"]
131
135
 
132
136
  [tool.mypy]
133
- python_version = "3.10"
137
+ python_version = "3.9"
134
138
  warn_return_any = false
135
139
  warn_unused_configs = true
136
140
  ignore_missing_imports = true
@@ -21,9 +21,12 @@ Async Example:
21
21
  >>> asyncio.run(main())
22
22
  """
23
23
 
24
+ from __future__ import annotations
25
+
24
26
  from .async_core import AsyncNanaSQLite
25
27
  from .cache import CacheType
26
- from .core import HAS_ORJSON, HAS_VALIDKIT, NanaSQLite
28
+ from .compat import HAS_ORJSON, HAS_VALIDKIT
29
+ from .core import NanaSQLite, V2Config
27
30
  from .exceptions import (
28
31
  NanaSQLiteCacheError,
29
32
  NanaSQLiteClosedError,
@@ -34,15 +37,24 @@ from .exceptions import (
34
37
  NanaSQLiteTransactionError,
35
38
  NanaSQLiteValidationError,
36
39
  )
40
+ from .hooks import CheckHook, ForeignKeyHook, PydanticHook, UniqueHook, ValidkitHook
41
+ from .protocols import NanaHook
37
42
 
38
- __version__ = "1.4.1dev2"
43
+ __version__ = "1.5.0dev2"
39
44
  __author__ = "Disnana"
40
45
  __all__ = [
41
46
  "NanaSQLite",
42
47
  "AsyncNanaSQLite",
48
+ "V2Config",
43
49
  "CacheType",
44
50
  "HAS_ORJSON",
45
51
  "HAS_VALIDKIT",
52
+ "NanaHook",
53
+ "CheckHook",
54
+ "UniqueHook",
55
+ "ForeignKeyHook",
56
+ "PydanticHook",
57
+ "ValidkitHook",
46
58
  "NanaSQLiteError",
47
59
  "NanaSQLiteValidationError",
48
60
  "NanaSQLiteDatabaseError",