feat: implement comprehensive query paradigm zoo system (issue #62)
- Created extensible BaseQueryParadigm interface with standardized QueryResult format - Implemented QueryParadigmRegistry for paradigm discovery and management - Added 5 working paradigms: SQL, FTS, GraphQL, JSONPath, Natural Language - Documented 9 additional paradigms: QBE, Batch Manipulation, Visual Query Builder, REST API, NoSQL, UNIX Pipeline, XPath/XQuery, RAG, Data Transformation - Integrated full CLI interface: list, search, show, exec, categories commands - Added comprehensive test suite with 23 test cases covering all components - Auto-registration system enables easy addition of new paradigms - Organized paradigms by category (structural, textual, semantic, visual, procedural, network) and complexity (beginner, intermediate, advanced) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
242
markitect/query_paradigms/cli.py
Normal file
242
markitect/query_paradigms/cli.py
Normal file
@@ -0,0 +1,242 @@
|
||||
"""
|
||||
CLI interface for query paradigm discovery and interaction.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from typing import Dict, Any
|
||||
|
||||
from .registry import registry
|
||||
|
||||
|
||||
def list_paradigms():
|
||||
"""List all available query paradigms."""
|
||||
paradigms = registry.list_all()
|
||||
|
||||
print(f"📚 MarkiTect Query Paradigms ({len(paradigms)} available)")
|
||||
print("=" * 50)
|
||||
|
||||
# Group by category
|
||||
categories = {}
|
||||
for paradigm in paradigms:
|
||||
if paradigm.category not in categories:
|
||||
categories[paradigm.category] = []
|
||||
categories[paradigm.category].append(paradigm)
|
||||
|
||||
for category, paradigm_list in categories.items():
|
||||
print(f"\n🏷️ {category.upper()} PARADIGMS")
|
||||
print("-" * 30)
|
||||
|
||||
for paradigm in paradigm_list:
|
||||
status = "✅ IMPLEMENTED" if paradigm.name in ['SQL', 'FTS', 'GraphQL', 'JSONPath', 'Natural Language'] else "📋 DOCUMENTED"
|
||||
print(f" {status} {paradigm.name} ({paradigm.complexity})")
|
||||
print(f" {paradigm.description}")
|
||||
print()
|
||||
|
||||
|
||||
def show_paradigm_details(name: str):
|
||||
"""Show detailed information about a specific paradigm."""
|
||||
paradigm = registry.get(name)
|
||||
|
||||
if not paradigm:
|
||||
print(f"❌ Paradigm '{name}' not found.")
|
||||
print("\nAvailable paradigms:")
|
||||
for p in registry.list_all():
|
||||
print(f" - {p.name}")
|
||||
return
|
||||
|
||||
status = "✅ IMPLEMENTED" if paradigm.name in ['SQL', 'FTS', 'GraphQL', 'JSONPath', 'Natural Language'] else "📋 DOCUMENTED"
|
||||
|
||||
print(f"🔍 {paradigm.name} Query Paradigm")
|
||||
print("=" * (len(paradigm.name) + 20))
|
||||
print(f"Status: {status}")
|
||||
print(f"Category: {paradigm.category}")
|
||||
print(f"Complexity: {paradigm.complexity}")
|
||||
print(f"Description: {paradigm.description}")
|
||||
print()
|
||||
|
||||
print("📝 Syntax Help:")
|
||||
print("-" * 15)
|
||||
print(paradigm.get_syntax_help())
|
||||
print()
|
||||
|
||||
print("💡 Examples:")
|
||||
print("-" * 12)
|
||||
examples = paradigm.get_examples()
|
||||
for i, example in enumerate(examples, 1):
|
||||
print(f"{i}. {example['name']}")
|
||||
print(f" {example['description']}")
|
||||
print(f" Query: {example['query']}")
|
||||
print()
|
||||
|
||||
|
||||
def search_paradigms(query: str):
|
||||
"""Search paradigms by name or description."""
|
||||
results = registry.search_paradigms(query)
|
||||
|
||||
if not results:
|
||||
print(f"❌ No paradigms found matching '{query}'")
|
||||
return
|
||||
|
||||
print(f"🔍 Search results for '{query}' ({len(results)} found)")
|
||||
print("=" * 40)
|
||||
|
||||
for paradigm in results:
|
||||
status = "✅ IMPLEMENTED" if paradigm.name in ['SQL', 'FTS', 'GraphQL', 'JSONPath', 'Natural Language'] else "📋 DOCUMENTED"
|
||||
print(f" {status} {paradigm.name} ({paradigm.category}, {paradigm.complexity})")
|
||||
print(f" {paradigm.description}")
|
||||
print()
|
||||
|
||||
|
||||
def execute_query(paradigm_name: str, query: str, config_str: str = None):
|
||||
"""Execute a query using specified paradigm."""
|
||||
paradigm = registry.get(paradigm_name)
|
||||
|
||||
if not paradigm:
|
||||
print(f"❌ Paradigm '{paradigm_name}' not found.")
|
||||
return
|
||||
|
||||
# Parse config if provided
|
||||
config = {}
|
||||
if config_str:
|
||||
try:
|
||||
config = json.loads(config_str)
|
||||
except json.JSONDecodeError:
|
||||
print("❌ Invalid JSON in config parameter")
|
||||
return
|
||||
|
||||
# Validate query first
|
||||
valid, error = paradigm.validate_query(query)
|
||||
if not valid:
|
||||
print(f"❌ Invalid query: {error}")
|
||||
return
|
||||
|
||||
print(f"🚀 Executing {paradigm.name} query...")
|
||||
print(f"Query: {query}")
|
||||
if config:
|
||||
print(f"Config: {config}")
|
||||
print()
|
||||
|
||||
try:
|
||||
result = paradigm.execute(query, config)
|
||||
|
||||
print(f"⏱️ Execution time: {result.execution_time_ms:.2f}ms")
|
||||
print(f"📊 Result count: {result.result_count}")
|
||||
print(f"✅ Success: {result.success}")
|
||||
|
||||
if result.error_message:
|
||||
print(f"❌ Error: {result.error_message}")
|
||||
|
||||
if result.metadata:
|
||||
print("\n📋 Metadata:")
|
||||
for key, value in result.metadata.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
if result.results:
|
||||
print(f"\n📄 Results:")
|
||||
for i, row in enumerate(result.results[:5], 1): # Show first 5 results
|
||||
print(f" {i}. {row}")
|
||||
|
||||
if len(result.results) > 5:
|
||||
print(f" ... and {len(result.results) - 5} more results")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Execution error: {e}")
|
||||
|
||||
|
||||
def list_categories():
|
||||
"""List all available categories."""
|
||||
categories = registry.get_categories()
|
||||
print("📂 Available Categories:")
|
||||
for category in sorted(categories):
|
||||
paradigms = registry.list_by_category(category)
|
||||
print(f" {category}: {len(paradigms)} paradigms")
|
||||
|
||||
|
||||
def show_translation_matrix():
|
||||
"""Show paradigm translation capabilities."""
|
||||
matrix = registry.get_translation_matrix()
|
||||
|
||||
print("🔄 Paradigm Translation Matrix")
|
||||
print("=" * 30)
|
||||
print("(Which paradigms can translate to which others)")
|
||||
print()
|
||||
|
||||
for source, targets in matrix.items():
|
||||
if targets:
|
||||
print(f"{source} → {', '.join(targets)}")
|
||||
else:
|
||||
print(f"{source} → (no translations available)")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main CLI entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="MarkiTect Query Paradigm Explorer",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s list # List all paradigms
|
||||
%(prog)s search "semantic" # Search paradigms
|
||||
%(prog)s show "Natural Language" # Show paradigm details
|
||||
%(prog)s exec FTS "documentation" # Execute query
|
||||
%(prog)s categories # List categories
|
||||
%(prog)s translations # Show translation matrix
|
||||
"""
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(dest='command', help='Available commands')
|
||||
|
||||
# List command
|
||||
subparsers.add_parser('list', help='List all available paradigms')
|
||||
|
||||
# Search command
|
||||
search_parser = subparsers.add_parser('search', help='Search paradigms')
|
||||
search_parser.add_argument('query', help='Search query')
|
||||
|
||||
# Show command
|
||||
show_parser = subparsers.add_parser('show', help='Show paradigm details')
|
||||
show_parser.add_argument('name', help='Paradigm name')
|
||||
|
||||
# Execute command
|
||||
exec_parser = subparsers.add_parser('exec', help='Execute query')
|
||||
exec_parser.add_argument('paradigm', help='Paradigm name')
|
||||
exec_parser.add_argument('query', help='Query to execute')
|
||||
exec_parser.add_argument('--config', help='JSON configuration')
|
||||
|
||||
# Categories command
|
||||
subparsers.add_parser('categories', help='List categories')
|
||||
|
||||
# Translations command
|
||||
subparsers.add_parser('translations', help='Show translation matrix')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
try:
|
||||
if args.command == 'list':
|
||||
list_paradigms()
|
||||
elif args.command == 'search':
|
||||
search_paradigms(args.query)
|
||||
elif args.command == 'show':
|
||||
show_paradigm_details(args.name)
|
||||
elif args.command == 'exec':
|
||||
execute_query(args.paradigm, args.query, args.config)
|
||||
elif args.command == 'categories':
|
||||
list_categories()
|
||||
elif args.command == 'translations':
|
||||
show_translation_matrix()
|
||||
except KeyboardInterrupt:
|
||||
print("\n👋 Goodbye!")
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user