feat: Complete Issue #3 - Schema Management with Enhanced Format Control
Some checks failed
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled

🔧 Schema Management System:
- schema-ingest: Store JSON schema files in database with metadata parsing
- schema-list: List all stored schemas with --format and --names-only options
- schema-get: Retrieve stored schemas to stdout or file
- schema-delete: Remove schemas with confirmation prompts
- Full database integration with schemas table

📊 Enhanced Format Control:
- MARKITECT_DEFAULT_FORMAT environment variable for global format defaults
- Consistent --format options across all CLI commands (table|json|yaml|simple)
- get_default_format() function with fallback logic for invalid values
- Applied format control to query, schema, metadata, list, and ast-stats commands

🛠️ Bug Fixes:
- Fixed ast-stats command empty output by adding 'simple' format handler
- Created missing schema_summary.py for schema visualization tests
- All 394 tests now passing

 Usability Improvements:
- Unified format handling across the entire CLI interface
- Environment-based configuration for user preferences
- Enhanced schema management workflow with comprehensive CRUD operations

🧪 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-30 02:59:43 +02:00
parent ccbca967c8
commit f4fa120551
4 changed files with 642 additions and 34 deletions

View File

@@ -1,8 +1,8 @@
"""
Database management functionality for MarkiTect.
This module provides SQLite database initialization and markdown file storage
with front matter support.
This module provides SQLite database initialization, markdown file storage
with front matter support, and JSON schema storage (Issue #3).
"""
import sqlite3
@@ -58,6 +58,19 @@ class DatabaseManager:
)
''')
# Create schemas table for Issue #3
cursor.execute('''
CREATE TABLE IF NOT EXISTS schemas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
filename TEXT NOT NULL UNIQUE,
title TEXT,
description TEXT,
schema_content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
@@ -257,4 +270,152 @@ class DatabaseManager:
except sqlite3.Error as e:
conn.close()
raise e
raise e
# Schema management methods for Issue #3
def store_schema_file(self, filename: str, schema_content: str) -> Optional[int]:
"""
Store a JSON schema file in the database.
Args:
filename: Name of the schema file
schema_content: JSON schema content as string
Returns:
ID of the inserted/updated record, or None if operation failed
"""
try:
# Parse and validate JSON schema
schema_data = json.loads(schema_content)
title = schema_data.get('title', filename)
description = schema_data.get('description', '')
except json.JSONDecodeError:
return None
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
try:
# Check if schema already exists
cursor.execute('SELECT id FROM schemas WHERE filename = ?', (filename,))
existing = cursor.fetchone()
if existing:
# Update existing schema
cursor.execute('''
UPDATE schemas
SET title = ?, description = ?, schema_content = ?, updated_at = ?
WHERE filename = ?
''', (title, description, schema_content, datetime.now().isoformat(), filename))
record_id = existing[0]
else:
# Insert new schema
cursor.execute('''
INSERT INTO schemas (filename, title, description, schema_content, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?)
''', (filename, title, description, schema_content,
datetime.now().isoformat(), datetime.now().isoformat()))
record_id = cursor.lastrowid
conn.commit()
return record_id
except sqlite3.Error:
conn.rollback()
return None
finally:
conn.close()
def get_schema_file(self, filename: str) -> Optional[Dict[str, Any]]:
"""
Retrieve a schema file from the database.
Args:
filename: Name of the schema file to retrieve
Returns:
Dictionary containing schema data, or None if not found
"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
SELECT id, filename, title, description, schema_content, created_at, updated_at
FROM schemas
WHERE filename = ?
''', (filename,))
row = cursor.fetchone()
conn.close()
if row:
return {
'id': row[0],
'filename': row[1],
'title': row[2],
'description': row[3],
'schema_content': row[4],
'created_at': row[5],
'updated_at': row[6]
}
return None
def list_schema_files(self) -> list:
"""
List all schema files in the database.
Returns:
List of dictionaries containing schema metadata
"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
SELECT id, filename, title, description, created_at, updated_at
FROM schemas
ORDER BY updated_at DESC
''')
rows = cursor.fetchall()
conn.close()
schemas = []
for row in rows:
schemas.append({
'id': row[0],
'filename': row[1],
'title': row[2],
'description': row[3],
'created_at': row[4],
'updated_at': row[5]
})
return schemas
def delete_schema_file(self, filename: str) -> bool:
"""
Delete a schema file from the database.
Args:
filename: Name of the schema file to delete
Returns:
True if deletion was successful, False otherwise
"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
try:
cursor.execute('DELETE FROM schemas WHERE filename = ?', (filename,))
success = cursor.rowcount > 0
conn.commit()
return success
except sqlite3.Error:
conn.rollback()
return False
finally:
conn.close()