Skip to content

Add table_mode parameter for complete table isolation in dictsqlite_v2 - #196

Merged
harumaki4649 merged 6 commits into
mainfrom
copilot/implement-table-mode-specification
Dec 6, 2025
Merged

harumaki4649 merged 6 commits into
mainfrom
copilot/implement-table-mode-specification

Conversation

Copilot AI commented Dec 5, 2025 •

Copy link
Copy Markdown
Contributor
  • Add table_mode parameter for DictSQLiteV4 and AsyncDictSQLite
  • Implement prefix mode (default) - backward compatible
  • Implement separate mode - complete table isolation using separate SQLite tables
  • Enhance TableProxy with complete dict operations
    • .get(key, default)
    • .pop(key, default)
    • .setdefault(key, default)
    • .update(dict)
    • iter support (for key in table)
    • delitem, values(), clear() for AsyncTableProxy
  • Add comprehensive tests (36 tests for table_mode)
    • Prefix/separate modes: basic, encryption, all storage modes, all persist modes, many tables, special chars, large data, updates, async, items/values
    • Dict operations: get, pop, setdefault, update, iter, delitem
    • Default behavior and backward compatibility
  • All 312 existing tests pass
  • Fix code review feedback (use is True instead of == True)
Original prompt

This section details on the original issue you should resolve

<issue_title>dictsqlite_v2のテーブルについて</issue_title>
<issue_description>dictsqlite_v2のテーブルに関してです。
テーブル機能なのでmode指定することで現在の仕様と、完全にテーブルを分離できる仕様のモードを実装することを検討してください。</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Dec 5, 2025
Copilot AI and others added 2 commits December 5, 2025 15:31
- Added TableMode enum (Prefix, Separate) in lib.rs
- Updated Config struct with table_mode field
- Updated DictSQLiteV4 and AsyncDictSQLite to accept table_mode parameter
- Added separate table storage methods in storage.rs
- Updated TableProxy and AsyncTableProxy to support both modes
- Added Modes.TABLE_PREFIX and Modes.TABLE_SEPARATE constants
- Added tests for the new table_mode feature

Co-authored-by: harumaki4649 <83683593+harumaki4649@users.noreply.github.com>
- Use kv_main instead of main for empty table name fallback
- Improve list_tables to filter out tables without kv_ prefix for security
- Remove unused TableMode import in storage.rs

Co-authored-by: harumaki4649 <83683593+harumaki4649@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement table mode specification for dictsqlite_v2 Add table_mode parameter for complete table isolation in dictsqlite_v2 Dec 5, 2025
Copilot AI requested a review from harumaki4649 December 5, 2025 15:44
@github-actions

github-actions Bot commented Dec 6, 2025 •

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bandit found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot 変更内容の報告書を日本語で作成してください(ファイルには書き込まずこのコメントに対する返信として返すこと)

変更内容報告書

概要

dictsqlite_v2のテーブル機能にtable_modeパラメータを追加し、現在の仕様と完全にテーブルを分離できる仕様の2つのモードを選択可能にしました。

追加されたモード

モード 説明 データ保存方式
prefix (デフォルト) 現在の動作と互換性あり キープレフィックス形式(例: users:alice)でkv_storeテーブルに保存
separate 完全なテーブル分離 各テーブル名ごとに独立したSQLiteテーブル(例: kv_users)を作成

変更ファイル

1. src/lib.rs

  • TableMode列挙型を追加(Prefix, Separate)
  • Config構造体にtable_modeフィールドを追加
  • DictSQLiteV4::new()にtable_modeパラメータを追加
  • TableProxyを両モード対応に更新
  • tables()メソッドを両モード対応に更新

2. src/async_ops.rs

  • AsyncDictSQLite::new()にtable_modeパラメータを追加
  • AsyncTableProxyを両モード対応に更新

3. src/storage.rs

  • 分離テーブルモード用のメソッドを追加:
    • sanitize_table_name() - テーブル名をSQL安全な識別子に変換
    • ensure_table_exists() - テーブル作成(存在しない場合)
    • get_with_table() - 指定テーブルから値を取得
    • set_with_table() - 指定テーブルに値を設定
    • delete_with_table() - 指定テーブルからキーを削除
    • keys_with_table() - 指定テーブルの全キーを取得
    • clear_table() - 指定テーブルをクリア
    • list_tables() - 全テーブル一覧を取得

4. python/dictsqlite/__init__.py

  • DictSQLiteとAsyncDictSQLiteにtable_modeパラメータを追加
  • Modes.TABLE_PREFIXとModes.TABLE_SEPARATE定数を追加

5. tests/test_table_mode.py (新規)

  • 8つのテストケースを追加(全てパス)

使用例

from dictsqlite import DictSQLiteV4, Modes

# プレフィックスモード(デフォルト)
db = DictSQLiteV4("test.db", table_mode=Modes.TABLE_PREFIX)

# 分離モード
db = DictSQLiteV4("test.db", table_mode=Modes.TABLE_SEPARATE)

users = db.table("users")
users["alice"] = {"name": "Alice"}

セキュリティ対策

  • テーブル名は英数字とアンダースコアのみに制限(SQLインジェクション対策)
  • list_tables()はkv_プレフィックスがないテーブルを除外

テスト結果

関連テスト66件全てパス

Added thorough testing for both prefix and separate modes:
- Encryption integration tests
- All storage modes (pickle, json, jsonb) tests
- All persist modes (memory, lazy, writethrough) tests
- Many tables (20+) tests
- Special character handling tests
- Large data tests
- Update/delete operations tests
- Async mode tests
- Table items/values tests
- Default behavior and backward compatibility tests

Co-authored-by: harumaki4649 <83683593+harumaki4649@users.noreply.github.com>

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot 規模の大きい変更のため2つのモードを徹底的にテストしてください。
また、ほかの箇所への影響を詳細にテストしなさい。

両モードの徹底的なテストを追加しました(コミット: 9e2e7b5)

テスト結果サマリー

table_mode テスト(28件全てパス)

カテゴリ prefix モード separate モード
基本操作 ✅ ✅
暗号化統合 ✅ ✅
全storage_mode (pickle/json/jsonb) ✅ ✅
全persist_mode (memory/lazy/writethrough) ✅ ✅
多数テーブル (20+) ✅ ✅
特殊文字 ✅ ✅
大容量データ ✅ ✅
更新/削除操作 ✅ ✅
async操作 ✅ ✅
items/values ✅ ✅
デフォルト動作 ✅ -
後方互換性 ✅ -

他機能への影響テスト(304件全てパス)

  • 基本操作: ✅
  • ストレージモード: ✅
  • 永続化モード: ✅
  • 暗号化: ✅
  • Safe Pickle: ✅
  • 非同期操作: ✅
  • テーブル機能: ✅
  • セキュリティ: ✅
  • 統合テスト: ✅
  • エッジケース: ✅

既存機能への影響はありません。

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot dictを使う操作すべてをテストするpytestがあるかを確認しなさい。ifから.getや.keysnado

dict操作を網羅するpytestを確認しました。以下に詳細を報告します:

dict操作のテストカバレッジ

既存のテストファイル(dict操作を網羅)

操作 テストファイル
__getitem__ (db[key]) test_basic_operations.py, test_comprehensive_all_functions.py
__setitem__ (db[key]=v) test_basic_operations.py, test_comprehensive_all_functions.py
__delitem__ (del db[key]) test_basic_operations.py, test_comprehensive_all_functions.py
__contains__ (if key in db) test_basic_operations.py, test_comprehensive_all_functions.py
__len__ (len(db)) test_basic_operations.py, test_comprehensive_all_functions.py
__iter__ (for key in db) test_basic_operations.py
.get(key, default) test_basic_operations.py, test_comprehensive_all_functions.py
.keys() test_basic_operations.py, test_dict_compat_api.py
.values() test_basic_operations.py, test_dict_compat_api.py
.items() test_basic_operations.py, test_dict_compat_api.py
.pop(key, default) test_basic_operations.py, test_dict_compat_api.py
.setdefault() test_dict_compat_api.py, test_comprehensive_all_functions.py
.update() test_basic_operations.py, test_dict_compat_api.py
.clear() test_basic_operations.py, test_comprehensive_all_functions.py

table_mode テストでの dict 操作カバレッジ

現在の test_table_mode.py では以下をテスト済み:

  • ✅ __getitem__ / __setitem__
  • ✅ __contains__ (in)
  • ✅ __len__
  • ✅ .keys()
  • ✅ .values()
  • ✅ .items()
  • ✅ .clear()
  • ❌ .get()
  • ❌ .pop()

結論: 主要なdict操作は網羅されています。.get()と.pop()はTableProxyで実装されていないため、テストがありませんが、これらはTableProxyの仕様上、提供されていません(直接.get()メソッドを使う場合はKeyErrorをキャッチして処理)。

Added to TableProxy and AsyncTableProxy:
- .get(key, default) method
- .pop(key, default) method
- .setdefault(key, default) method
- .update(dict) method
- __iter__ for iteration support (for key in table)
- __delitem__ for AsyncTableProxy
- values() for AsyncTableProxy
- clear() for AsyncTableProxy

Added comprehensive tests (8 new tests):
- test_table_proxy_get_method
- test_table_proxy_pop_method
- test_table_proxy_setdefault_method
- test_table_proxy_update_method
- test_table_proxy_iter_method
- test_table_proxy_delitem
- test_async_table_proxy_all_dict_ops
- test_table_proxy_bytes_mode

All 312 tests pass.

Co-authored-by: harumaki4649 <83683593+harumaki4649@users.noreply.github.com>

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot dictsqliteの存在意義はsqliteをdictとして扱えることです。dictでできることができなければ存在意義はありません。tableproxyの強化と.get,.popやdictで...

TableProxyに完全なdict操作を追加しました(コミット: 3aa4f6d)

追加されたメソッド

TableProxy / AsyncTableProxy

操作 メソッド 説明
.get(key, default) ✅ デフォルト値付きで値を取得
.pop(key, default) ✅ キーを削除して値を返す
.setdefault(key, default) ✅ 存在しない場合のみ設定
.update(dict) ✅ 辞書で一括更新
for key in table ✅ イテレーション
del table[key] ✅ キー削除
table.keys() ✅ 全キー取得
table.values() ✅ 全値取得
table.items() ✅ 全アイテム取得
table.clear() ✅ 全削除
key in table ✅ 存在確認
len(table) ✅ 件数取得

テスト結果

  • table_mode テスト: 36件パス
  • 全テスト: 312件パス

両モード(prefix/separate)と全ストレージモード(pickle/json/jsonb/bytes)で動作確認済みです。

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a table_mode parameter to DictSQLite v4.2 to provide users with a choice between two table isolation strategies: prefix mode (default, backward compatible) and separate mode (complete SQLite table isolation).

Key changes:

  • Introduced TableMode enum with Prefix (default) and Separate modes
  • Enhanced both TableProxy and AsyncTableProxy with complete dict-like operations (get, pop, setdefault, update, iteration support)
  • Added comprehensive storage engine methods for separate table operations with proper SQL sanitization
  • Implemented 36 tests covering both modes across various scenarios (encryption, storage modes, persistence modes, large data)

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
dictsqlite_v2/dictsqlite/tests/test_table_mode.py New comprehensive test suite with 36 tests covering both table modes, dict operations, and edge cases
dictsqlite_v2/dictsqlite/src/storage.rs Added 7 new methods for separate table mode operations with proper SQL sanitization and error handling
dictsqlite_v2/dictsqlite/src/lib.rs Introduced TableMode enum, enhanced TableProxy with dict operations, added iterator support, and updated table operations to support both modes
dictsqlite_v2/dictsqlite/src/async_ops.rs Enhanced AsyncTableProxy with complete dict operations matching sync implementation, added async iterator, fixed repr string
dictsqlite_v2/dictsqlite/python/dictsqlite/__init__.py Added table_mode parameter to both sync and async constructors, documented new table mode constants

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

for name in table_names:
table = db.table(name)
table["key1"] = {"test": True}
assert table["key1"]["test"] == True

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use is True or assert table["key1"]["test"] instead of == True for boolean comparison. Direct comparison with boolean literals using == is considered less pythonic than using identity checks (is) or just asserting the boolean value directly.

Copilot uses AI. Check for mistakes.
for name in table_names:
table = db.table(name)
table["key1"] = {"test": True}
assert table["key1"]["test"] == True

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use is True or assert table["key1"]["test"] instead of == True for boolean comparison. Direct comparison with boolean literals using == is considered less pythonic than using identity checks (is) or just asserting the boolean value directly.

Suggested change
assert table["key1"]["test"] == True
assert table["key1"]["test"]

Copilot uses AI. Check for mistakes.

# Test .get() with default value
result = users.get("nonexistent", {"default": True})
assert result["default"] == True

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use is True or assert result["default"] instead of == True for boolean comparison. Direct comparison with boolean literals using == is considered less pythonic than using identity checks (is) or just asserting the boolean value directly.

Suggested change
assert result["default"] == True
assert result["default"] is True

Copilot uses AI. Check for mistakes.

# Test .pop() with non-existing key and default
result = users.pop("nonexistent", {"default": True})
assert result["default"] == True

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use is True or assert result["default"] instead of == True for boolean comparison. Direct comparison with boolean literals using == is considered less pythonic than using identity checks (is) or just asserting the boolean value directly.

Suggested change
assert result["default"] == True
assert result["default"] is True

Copilot uses AI. Check for mistakes.
# Test get()
assert users.get("alice")["name"] == "Alice"
assert users.get("nonexistent") is None
assert users.get("nonexistent", {"default": True})["default"] == True

Copilot AI Dec 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use is True instead of == True for boolean comparison. Direct comparison with boolean literals using == is considered less pythonic than using identity checks (is).

Suggested change
assert users.get("nonexistent", {"default": True})["default"] == True
assert users.get("nonexistent", {"default": True})["default"] is True

Copilot uses AI. Check for mistakes.
Changed `== True` to `is True` for boolean comparisons as per code review feedback.

Co-authored-by: harumaki4649 <83683593+harumaki4649@users.noreply.github.com>

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot あなたのレビューコメントを適切に判断し、対応しなさい。

レビューコメントに対応しました(コミット: df7bfb5)

5箇所の== Trueをis Trueに修正しました:

  • test_prefix_mode_table_special_characters (line 560)
  • test_separate_mode_table_special_characters (line 584)
  • test_table_proxy_get_method (line 914)
  • test_table_proxy_pop_method (line 946)
  • test_async_table_proxy_all_dict_ops (line 1129)

全36テストがパスしています。

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot - table_mode="separate" を選ぶと物理的に別SQLiteテーブル(kv_<sanitized_name>)に保存されるため、prefixモードの既存データは見えなくなります。テー�...

コメントが途中で切れているようです。table_mode="separate"について、確認や変更をお求めでしょうか?具体的にお聞きしたい点を教えてください。

現在の実装では、table_mode="separate"を選ぶと各テーブルが物理的に別のSQLiteテーブル(kv_{table_name}形式)として作成されます。

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot 他のaiに言われたことなんだが、

  • table_mode="separate" を選ぶと物理的に別SQLiteテーブル(kv_<sanitized_name>)に保存されるため、prefixモードの既存�...

コメントが途中で切れています。他のAIからどのようなフィードバックがあったか、完全なメッセージを教えていただけますか?

現在のtable_mode="separate"の実装について説明します:

  • 各テーブルはkv_{table_name}形式で物理的に別のSQLiteテーブルとして作成されます
  • テーブル名はSQLインジェクション対策として英数字とアンダースコアのみに制限(サニタイズ)されます
  • 空のテーブル名はkv_mainにフォールバックします

他のAIからの指摘が何か具体的にあれば、対応を検討します。

Copilot AI commented Dec 6, 2025

Copy link
Copy Markdown
Contributor Author

@copilot いわれたことはこれだけだ。banditの警告の確認と対応などを求められている

banditセキュリティ分析を実行しました。

結果

ソースコード(python/)

  • Medium/High: なし ✅
  • Low: 6件(すべて#nosecでスキップ済み)

テストコード(tests/)

  • Medium/High: なし ✅
  • Low: 861件(すべてB101:assert_used - pytestでassertを使用するのは標準的な方法なので問題なし)

結論

セキュリティ上の問題は検出されませんでした。テストファイルでのassert使用はpytestの標準的な使い方であり、許容されます。

@harumaki4649
harumaki4649 merged commit 42ce560 into main Dec 6, 2025
55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants