## LLVM Call Instruction Modularization - Moved MirInstruction::Call lowering to separate instructions/call.rs - Follows the principle of one MIR instruction per file - Call implementation was already complete, just needed modularization ## Phase 21 Documentation - Moved all Phase 21 content to private/papers/paper-f-self-parsing-db/ - Preserved AI evaluations from Gemini and Codex - Academic paper potential confirmed by both AIs - Self-parsing AST database approach validated ## Next Steps - Continue monitoring ChatGPT5's LLVM improvements - Consider creating separate nyash-llvm-compiler crate when LLVM layer is stable - This will reduce build times by isolating LLVM dependencies 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
11 KiB
Phase 21: 技術的考慮事項
🏗️ アーキテクチャ設計
レイヤー構造
┌─────────────────────────────┐
│ 開発ツール層 │ (VSCode, CLI, Web UI)
├─────────────────────────────┤
│ API層 │ (GraphQL/REST)
├─────────────────────────────┤
│ CodeDB抽象層 │ (統一インターフェース)
├─────────────────────────────┤
│ SQLite実装層 │ (具体的なDB操作)
├─────────────────────────────┤
│ ストレージ層 │ (ローカル/リモート)
└─────────────────────────────┘
🔐 セキュリティ考慮事項
アクセス制御
-- ユーザー権限管理
CREATE TABLE permissions (
user_id INTEGER,
resource_type TEXT,
resource_id INTEGER,
permission TEXT CHECK(permission IN ('read', 'write', 'admin')),
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
granted_by INTEGER,
PRIMARY KEY (user_id, resource_type, resource_id, permission)
);
-- 監査ログ
CREATE TABLE audit_log (
id INTEGER PRIMARY KEY,
user_id INTEGER,
action TEXT,
resource_type TEXT,
resource_id INTEGER,
old_value TEXT,
new_value TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ip_address TEXT,
session_id TEXT
);
SQLインジェクション対策
box SecureCodeDB from CodeDB {
// パラメータ化クエリを強制
query(sql, params) {
// SQLをパースして危険な構文をチェック
local ast = me.parseSql(sql)
if me.hasDangerousPattern(ast) {
throw new SecurityError("Dangerous SQL pattern detected")
}
return from CodeDB.query(sql, params)
}
// ホワイトリスト方式のテーブル名検証
validateTableName(name) {
if not name.matches("^[a-z_]+$") {
throw new SecurityError("Invalid table name")
}
}
}
🚀 パフォーマンス最適化
インデックス戦略
-- 頻繁なクエリ用インデックス
CREATE INDEX idx_boxes_namespace ON boxes(namespace);
CREATE INDEX idx_methods_box_id ON methods(box_id);
CREATE INDEX idx_deps_from ON dependencies(from_type, from_id);
CREATE INDEX idx_deps_to ON dependencies(to_type, to_id);
-- 複合インデックス
CREATE INDEX idx_box_namespace_name ON boxes(namespace, name);
CREATE INDEX idx_method_box_name ON methods(box_id, name);
-- 部分インデックス(アクティブなものだけ)
CREATE INDEX idx_active_boxes ON boxes(name)
WHERE deleted_at IS NULL;
クエリ最適化
box QueryOptimizer {
cache: MapBox
// クエリ結果のキャッシング
cachedQuery(sql, params, ttl) {
local key = me.hash(sql + params.toString())
if me.cache.has(key) {
local cached = me.cache.get(key)
if cached.timestamp + ttl > now() {
return cached.result
}
}
local result = me.db.query(sql, params)
me.cache.set(key, {
result: result,
timestamp: now()
})
return result
}
}
🔄 同期・レプリケーション
マルチデバイス同期
box CodeDBSync {
local: CodeDB
remote: RemoteCodeDB
// 変更を追跡
trackChanges() {
CREATE TRIGGER track_box_changes
AFTER INSERT OR UPDATE OR DELETE ON boxes
BEGIN
INSERT INTO sync_queue (
table_name, operation, entity_id, data
) VALUES (
'boxes',
CASE
WHEN OLD.id IS NULL THEN 'INSERT'
WHEN NEW.id IS NULL THEN 'DELETE'
ELSE 'UPDATE'
END,
COALESCE(NEW.id, OLD.id),
json_object('old', OLD, 'new', NEW)
);
END;
}
// 差分同期
sync() {
local changes = me.local.query("
SELECT * FROM sync_queue
WHERE synced_at IS NULL
ORDER BY created_at
")
for change in changes {
me.remote.applyChange(change)
me.local.markSynced(change.id)
}
}
}
🎯 互換性戦略
ファイルシステムとの相互変換
box FileDBBridge {
// DB→ファイル エクスポート
exportToFiles(outputDir) {
local boxes = me.db.query("SELECT * FROM boxes")
for box in boxes {
local path = outputDir + "/" +
box.namespace.replace(".", "/") + "/" +
box.name + ".nyash"
local file = new FileBox(path)
file.write(me.generateFileContent(box))
}
}
// ファイル→DB インポート
importFromFiles(sourceDir) {
local files = FileBox.glob(sourceDir + "/**/*.nyash")
me.db.beginTransaction()
try {
for file in files {
local ast = Parser.parse(file.read())
me.importAST(ast, file.path)
}
me.db.commit()
} catch (e) {
me.db.rollback()
throw e
}
}
}
🔍 高度な分析機能
コードメトリクス
-- 循環的複雑度の計算
CREATE VIEW method_complexity AS
SELECT
m.id,
b.name || '.' || m.name as full_name,
(
SELECT COUNT(*)
FROM json_each(m.body)
WHERE value LIKE '%if%'
OR value LIKE '%loop%'
OR value LIKE '%catch%'
) + 1 as cyclomatic_complexity
FROM methods m
JOIN boxes b ON m.box_id = b.id;
-- コード行数統計
CREATE VIEW code_stats AS
SELECT
COUNT(DISTINCT b.id) as total_boxes,
COUNT(DISTINCT m.id) as total_methods,
SUM(LENGTH(m.body) - LENGTH(REPLACE(m.body, char(10), ''))) as total_lines,
AVG(LENGTH(m.body) - LENGTH(REPLACE(m.body, char(10), ''))) as avg_method_lines
FROM boxes b
LEFT JOIN methods m ON b.id = m.box_id;
依存関係の可視化
box DependencyAnalyzer {
// 影響範囲分析
getImpactedEntities(changedEntity) {
return me.db.query("
WITH RECURSIVE impacted AS (
-- 直接依存
SELECT to_type, to_id, 1 as level
FROM dependencies
WHERE from_type = ? AND from_id = ?
UNION
-- 推移的依存
SELECT d.to_type, d.to_id, i.level + 1
FROM dependencies d
JOIN impacted i ON
d.from_type = i.to_type AND
d.from_id = i.to_id
WHERE i.level < 5 -- 最大5階層まで
)
SELECT DISTINCT * FROM impacted
ORDER BY level
", [changedEntity.type, changedEntity.id])
}
}
🌐 分散開発対応
ブランチ・マージ戦略
-- ブランチ管理
CREATE TABLE branches (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE NOT NULL,
base_commit_id INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by INTEGER,
is_active BOOLEAN DEFAULT TRUE
);
-- コミット(変更セット)
CREATE TABLE commits (
id INTEGER PRIMARY KEY,
branch_id INTEGER,
parent_commit_id INTEGER,
message TEXT,
author INTEGER,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
changes JSON, -- 変更の詳細
FOREIGN KEY (branch_id) REFERENCES branches(id)
);
コンフリクト解決
box ConflictResolver {
// 3-way マージ
merge(base, mine, theirs) {
if mine == theirs {
return mine // 変更なし or 同じ変更
}
if base == mine {
return theirs // 相手のみ変更
}
if base == theirs {
return mine // 自分のみ変更
}
// 両方変更 - コンフリクト
return me.resolveConflict(base, mine, theirs)
}
resolveConflict(base, mine, theirs) {
// AST レベルでのマージを試みる
local baseAST = Parser.parse(base)
local mineAST = Parser.parse(mine)
local theirsAST = Parser.parse(theirs)
// メソッド単位でマージ可能か確認
if me.canMergeAtMethodLevel(baseAST, mineAST, theirsAST) {
return me.mergeASTs(baseAST, mineAST, theirsAST)
}
// マージ不可 - ユーザーに選択させる
throw new MergeConflict(base, mine, theirs)
}
}
📊 メトリクス・モニタリング
パフォーマンス追跡
-- クエリパフォーマンスログ
CREATE TABLE query_performance (
id INTEGER PRIMARY KEY,
query_hash TEXT,
query_text TEXT,
execution_time_ms INTEGER,
rows_affected INTEGER,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- DB統計情報
CREATE VIEW db_stats AS
SELECT
(SELECT COUNT(*) FROM boxes) as total_boxes,
(SELECT COUNT(*) FROM methods) as total_methods,
(SELECT COUNT(*) FROM dependencies) as total_dependencies,
(SELECT page_count * page_size FROM pragma_page_count(), pragma_page_size()) as db_size_bytes,
(SELECT COUNT(*) FROM compile_cache) as cached_compilations;
🔮 将来の拡張性
プラグインアーキテクチャ
box CodeDBPlugin {
// フック機能
hooks: MapBox
register(event, handler) {
if not me.hooks.has(event) {
me.hooks.set(event, new ArrayBox())
}
me.hooks.get(event).push(handler)
}
trigger(event, data) {
if me.hooks.has(event) {
for handler in me.hooks.get(event) {
handler(data)
}
}
}
}
// 使用例:自動フォーマッター
box AutoFormatter from CodeDBPlugin {
birth() {
me.register("before_save", me.formatCode)
}
formatCode(data) {
if data.entity_type == "method" {
data.body = Formatter.format(data.body)
}
}
}
AI統合の準備
-- ベクトル埋め込み保存
CREATE TABLE embeddings (
id INTEGER PRIMARY KEY,
entity_type TEXT,
entity_id INTEGER,
embedding BLOB, -- float配列をBLOBで保存
model_version TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 類似性検索用の仮想テーブル(将来的にベクトル検索エンジンと統合)
CREATE VIRTUAL TABLE vector_search USING vector_index(
embedding FLOAT[768]
);
これらの技術的考慮事項を踏まえて、段階的に実装を進めることで、 安全で高性能なデータベース駆動開発環境を実現できるにゃ!