hana-cli
Version:
HANA Developer Command Line Interface
429 lines (399 loc) • 13.7 kB
text/typescript
/**
* Next steps suggestions and troubleshooting tips
* Provides context-aware guidance after command execution
*/
export interface NextStep {
command: string;
description: string;
parameters?: Record<string, string>;
reason?: string;
}
export interface TroubleshootingTip {
issue: string;
solution: string;
command?: string;
parameters?: Record<string, any>;
}
export interface TroubleshootingGuide {
command: string;
commonIssues: TroubleshootingTip[];
prerequisites: string[];
tips: string[];
}
/**
* Get suggested next steps after executing a command
*/
export function getNextSteps(command: string, output?: string): NextStep[] {
const nextStepsMap: Record<string, NextStep[]> = {
'status': [
{
command: 'schemas',
description: 'Explore available schemas',
reason: 'Now that connection is verified, discover what data you can access',
},
{
command: 'healthCheck',
description: 'Check system health',
reason: 'Verify the database is in good condition',
},
{
command: 'version',
description: 'Check database version',
reason: 'Understand which HANA version you are on',
},
],
'schemas': [
{
command: 'tables',
description: 'List tables in a schema',
parameters: { schema: '<schema-name>' },
reason: 'Explore the tables in one of the schemas you discovered',
},
{
command: 'views',
description: 'List views in a schema',
parameters: { schema: '<schema-name>' },
reason: 'See what views are available',
},
],
'tables': [
{
command: 'inspectTable',
description: 'View detailed table structure',
parameters: { table: '<table-name>', schema: '<schema-name>' },
reason: 'Get columns, types, keys, and indexes',
},
{
command: 'dataProfile',
description: 'Analyze table data distribution',
parameters: { table: '<table-name>', schema: '<schema-name>' },
reason: 'Understand data quality and patterns',
},
],
'inspectTable': [
{
command: 'dataProfile',
description: 'Profile the table data',
parameters: { table: '<table-name>', schema: '<schema-name>' },
reason: 'Now that you know the structure, analyze the data',
},
{
command: 'export',
description: 'Export table data',
parameters: { table: '<table-name>', schema: '<schema-name>', filename: '<output.csv>' },
reason: 'Extract data for analysis',
},
],
'dataProfile': [
{
command: 'duplicateDetection',
description: 'Find duplicate records',
parameters: { table: '<table-name>', schema: '<schema-name>' },
reason: 'If profile shows many duplicates, investigate further',
},
{
command: 'dataValidator',
description: 'Validate data quality',
parameters: { table: '<table-name>', schema: '<schema-name>', rulesFile: '<rules.json>' },
reason: 'Apply validation rules to ensure data quality',
},
{
command: 'export',
description: 'Export profiled data',
parameters: { table: '<table-name>', schema: '<schema-name>', filename: '<output.csv>' },
reason: 'Save the data for further analysis',
},
],
'export': [
{
command: 'import',
description: 'Import the exported data elsewhere',
parameters: { filename: '<exported-file>', table: '<target-table>', schema: '<target-schema>' },
reason: 'Load the exported data into another table or database',
},
],
'import': [
{
command: 'dataValidator',
description: 'Validate imported data',
parameters: { table: '<table-name>', schema: '<schema-name>', rulesFile: '<rules.json>' },
reason: 'Ensure imported data meets quality standards',
},
{
command: 'dataProfile',
description: 'Profile the imported data',
parameters: { table: '<table-name>', schema: '<schema-name>' },
reason: 'Verify data distribution after import',
},
{
command: 'duplicateDetection',
description: 'Check for duplicates',
parameters: { table: '<table-name>', schema: '<schema-name>' },
reason: 'Ensure no duplicate records were imported',
},
],
'duplicateDetection': [
{
command: 'dataValidator',
description: 'Run comprehensive validation',
parameters: { table: '<table-name>', schema: '<schema-name>', rulesFile: '<rules.json>' },
reason: 'Check for other data quality issues beyond duplicates',
},
],
'compareSchema': [
{
command: 'schemaClone',
description: 'Clone schema structure',
parameters: { sourceSchema: '<source>', targetSchema: '<target>' },
reason: 'If differences found, you may want to sync schemas',
},
],
'healthCheck': [
{
command: 'memoryAnalysis',
description: 'Analyze memory usage',
reason: 'If health check shows memory issues, investigate further',
},
{
command: 'alerts',
description: 'View system alerts',
reason: 'Check for any active warnings or alerts',
},
],
'memoryAnalysis': [
{
command: 'expensiveStatements',
description: 'Find expensive SQL statements',
reason: 'Identify queries consuming resources',
},
{
command: 'tableHotspots',
description: 'Find heavily accessed tables',
reason: 'Understand which tables are causing memory pressure',
},
],
'backup': [
{
command: 'backupStatus',
description: 'Monitor backup progress',
reason: 'Check that backup is proceeding successfully',
},
{
command: 'backupList',
description: 'Verify backup in catalog',
reason: 'Confirm backup was completed and cataloged',
},
],
};
return nextStepsMap[command] || [];
}
/**
* Get troubleshooting guide for a command
*/
export function getTroubleshootingGuide(command: string): TroubleshootingGuide | null {
const guides: Record<string, TroubleshootingGuide> = {
'import': {
command: 'import',
commonIssues: [
{
issue: 'Column mismatch error',
solution: 'Use matchMode parameter to control how columns are matched. Try matchMode="name" to match by column name instead of position.',
command: 'import',
parameters: { matchMode: 'name' },
},
{
issue: 'File not found',
solution: 'Use absolute file paths instead of relative paths. Check that file exists at the specified location.',
},
{
issue: 'Import takes too long',
solution: 'For large files, increase timeout and set memory limits.',
command: 'import',
parameters: { maxFileSizeMB: 500, timeoutSeconds: 3600 },
},
{
issue: 'Some rows fail to import',
solution: 'Use skipWithErrors and maxErrorsAllowed to continue import despite errors. Run with dryRun first to preview issues.',
command: 'import',
parameters: { skipWithErrors: true, maxErrorsAllowed: 100, dryRun: true },
},
{
issue: 'Data types don\'t match',
solution: 'Check table structure first with inspectTable. Ensure CSV data types match table column types.',
command: 'inspectTable',
parameters: { table: '<table-name>', schema: '<schema-name>' },
},
],
prerequisites: [
'Target table must exist',
'User must have INSERT privilege on table',
'File must be accessible from server',
'Sufficient disk space for temporary files',
],
tips: [
'Always use dryRun:true first to preview the import',
'Check table structure with inspectTable before importing',
'For large files, increase timeoutSeconds parameter',
'Use matchMode="name" if column order differs between file and table',
],
},
'export': {
command: 'export',
commonIssues: [
{
issue: 'Export file is too large',
solution: 'Use WHERE clause to filter rows, or export in batches.',
command: 'export',
parameters: { where: "DATE >= '2025-01-01'" },
},
{
issue: 'Permission denied writing file',
solution: 'Check that output directory exists and is writable. Use absolute path.',
},
{
issue: 'Export timeout',
solution: 'For large tables, consider filtering data or exporting specific columns only.',
},
],
prerequisites: [
'User must have SELECT privilege on table',
'Output directory must be writable',
'Sufficient disk space for output file',
],
tips: [
'Use WHERE clause to filter data and reduce file size',
'Excel files (.xlsx) are limited to ~1 million rows',
'For large exports, CSV is faster than Excel',
],
},
'dataProfile': {
command: 'dataProfile',
commonIssues: [
{
issue: 'Profile takes very long on large tables',
solution: 'Profile specific columns instead of entire table.',
command: 'dataProfile',
parameters: { columns: ['COLUMN1', 'COLUMN2'] },
},
{
issue: 'Out of memory error',
solution: 'Profile fewer columns at a time, or profile a sample of the data.',
},
],
prerequisites: [
'User must have SELECT privilege',
'Sufficient memory for statistics calculation',
],
tips: [
'Profiling large tables can take several minutes',
'Use columns parameter to profile only specific columns',
'Good to run before data validation',
],
},
'tables': {
command: 'tables',
commonIssues: [
{
issue: 'No tables found',
solution: 'Check schema name is correct (case-sensitive). Verify user has access to schema.',
command: 'schemas',
},
{
issue: 'Too many tables returned',
solution: 'Use table parameter with wildcard to filter results.',
command: 'tables',
parameters: { table: 'PREFIX%' },
},
],
prerequisites: [
'Schema must exist',
'User must have CATALOG READ privilege or object privileges',
],
tips: [
'Schema names are case-sensitive',
'Use % wildcard in table parameter to filter',
],
},
'status': {
command: 'status',
commonIssues: [
{
issue: 'Connection refused',
solution: 'Check database credentials in .env or default-env.json file.',
},
{
issue: 'Authentication failed',
solution: 'Verify username and password are correct. Check if user account is locked.',
},
],
prerequisites: [
'Database must be running',
'Network connectivity to database',
'Valid credentials configured',
],
tips: [
'Run this first to verify connection',
'Shows current user and granted roles',
],
},
'healthCheck': {
command: 'healthCheck',
commonIssues: [
{
issue: 'Health check reports issues',
solution: 'Follow recommendations in the output. Run diagnose for detailed analysis.',
command: 'diagnose',
},
{
issue: 'Memory alerts',
solution: 'Run memory analysis to identify memory-intensive tables.',
command: 'memoryAnalysis',
},
],
prerequisites: [
'User needs monitoring privileges',
],
tips: [
'Run periodically to catch issues early',
'Pay attention to alerts and warnings',
],
},
};
return guides[command] || null;
}
/**
* Get command-specific tips based on output analysis
*/
export function analyzeOutputForTips(command: string, output: string): string[] {
const tips: string[] = [];
const outputLower = output.toLowerCase();
// Import-specific tips
if (command === 'import') {
if (outputLower.includes('error') || outputLower.includes('failed')) {
tips.push('💡 Try using dryRun:true to preview issues before actual import');
tips.push('💡 Use skipWithErrors:true to continue import despite errors');
}
}
// Memory-related tips
if (command === 'memoryAnalysis') {
if (outputLower.includes('high') || outputLower.includes('memory')) {
tips.push('💡 Consider running expensiveStatements to find resource-intensive queries');
tips.push('💡 Check tableHotspots to identify heavily accessed tables');
}
}
// Table listing tips
if (command === 'tables') {
const tableCount = (output.match(/\│/g) || []).length;
if (tableCount > 100) {
tips.push('💡 Many tables found - use table parameter with wildcard to filter (e.g., table="SALES%")');
}
}
// Health check tips
if (command === 'healthCheck') {
if (outputLower.includes('warning') || outputLower.includes('alert')) {
tips.push('💡 Run diagnose command for detailed analysis of issues');
tips.push('💡 Check alerts command for active system alerts');
}
}
return tips;
}