UNPKG

hana-cli

Version:
650 lines (441 loc) 17.9 kB
# Utils Directory This directory contains reusable utility modules that provide core functionality for the SAP HANA Developer CLI tool. These utilities handle database connections, CLI interactions, security, and various helper functions used throughout the application. ## Table of Contents - [Core Utilities](#core-utilities) - [base.js](#basejs) - [connections.js](#connectionsjs) - [dbInspect.js](#dbinspectjs) - [locale.js](#localejs) - [sqlInjection.js](#sqlinjectionjs) - [versionCheck.js](#versioncheckjs) - [CLI Integration Utilities](#cli-integration-utilities) - [btp.js](#btpjs) - [cf.js](#cfjs) - [xs.js](#xsjs) - [Database Utilities](#database-utilities) - [massConvert.js](#massconvertjs) - [database/](#database-subfolder) - [Usage Examples](#usage-examples) --- ## Core Utilities ### base.js **Module**: `base` - Central functionality shared by all commands The base module is the foundation of the CLI tool, providing shared functionality that is used across all commands. **Key Features**: - Database connection management - Terminal UI components (spinners, progress bars, tables) - Color output support via chalk - Prompts handling and validation - Debugging utilities - Internationalization (i18n) support via text bundles - Command builder for yargs - File opening utilities **Key Exports**: ```javascript export const dbClass // sap-hdb-promisfied instance export const colors // Chalk color utilities export const debug // Debug logging function export const terminal // Terminal-kit instance export const bundle // Text bundle for i18n export const sqlInjection // SQL injection protection export const tableOptions // Default table rendering options ``` **Important Functions**: - `createDBConnection(options)` - Create and return a database connection - `getBuilder(input, iConn, iDebug)` - Initialize Yargs builder with connection and debug groups - `setPrompts(newPrompts)` / `getPrompts()` - Manage command prompts - `startSpinnerInt()` / `stopSpinnerInt()` - Control terminal spinner - `clearConnection()` - Clear the database connection - `blankLine()` - Output a blank line to console **Usage**: ```javascript import * as base from './utils/base.js' const db = await base.createDBConnection() base.colors.green('Success!') ``` --- ### connections.js **Module**: `connections` - Helper utility for making connections to HANA DB and determining connection settings Manages database connectivity and configuration file discovery, supporting multiple connection methods and secure credential management. **Key Features**: - Searches for configuration files in current and parent directories - Supports multiple connection file types (default-env.json, .env, .cdsrc-private.json) - Handles admin connection overrides - Integrates with SAP CAP/CDS projects - Supports secure credential lookup via `cds bind` **Key Functions**: - `getFileCheckParents(filename)` - Search for a file in current and parent directories (up to 5 levels) - `getPackageJSON()` - Find package.json file - `getMTA()` - Find mta.yaml file - `getDefaultEnv()` - Find default-env.json file - `getDefaultEnvAdmin()` - Find default-env-admin.json file - `getEnv()` - Find .env file **Connection Resolution Order**: 1. Admin option: `default-env-admin.json` 2. CDS bind: `.cdsrc-private.json` (most secure, cloud-based lookup) 3. Local env: `.env` file with VCAP_SERVICES 4. Custom file via `--conn` parameter 5. Default: `default-env.json` 6. Fallback: `${homedir}/.hana-cli/default.json` **Usage**: ```javascript import * as conn from './utils/connections.js' const envFile = conn.getDefaultEnv() const pkgJson = conn.getPackageJSON() ``` --- ### dbInspect.js **Module**: `dbInspect` - Database Object Dynamic Inspection and Metadata processing Provides utilities for inspecting and retrieving metadata about various SAP HANA database objects. **Key Features**: - Retrieve HANA database version information - Inspect views, including calculation views - Get database object metadata - Handle different HANA versions (1.x and 2.x) - Support for column views, calculation views, and structured privileges **Key Functions**: - `getHANAVersion(db)` - Return the HANA DB version and major version number - `isCalculationView(db, schema, viewId)` - Check if a view is a calculation view - `getView(db, schema, viewId)` - Get DB view details including metadata **Usage**: ```javascript import * as dbInspect from './utils/dbInspect.js' const version = await dbInspect.getHANAVersion(db) const isCalcView = await dbInspect.isCalculationView(db, 'MYSCHEMA', 'MY_VIEW') const viewDetails = await dbInspect.getView(db, 'MYSCHEMA', 'MY_VIEW') ``` --- ### locale.js **Module**: Simple locale detection utility Detects the user's locale from environment variables for internationalization support. **Key Functions**: - `getLocale(env)` - Get the locale from environment variables (LC_ALL, LC_MESSAGES, LANG, or LANGUAGE) **Usage**: ```javascript import * as locale from './utils/locale.js' const userLocale = locale.getLocale() ``` --- ### sqlInjection.js **Module**: `sqlInjection` - SQL Injection Protection Utilities Provides security utilities to protect against SQL injection attacks by validating SQL parameters. **Key Features**: - Whitespace character validation - SQL separator character detection - Quoted parameter validation - Token-based parameter validation - Protection against malicious SQL input **Key Exports**: ```javascript export const whitespaceTable // Table of valid whitespace characters export const separatorTable // Table of SQL separator characters ``` **Key Functions**: - `isAcceptableParameter(value, maxToken)` - Check if a parameter is safe (default: 1 token max) - `isAcceptableQuotedParameter(value)` - Check if a quoted parameter contains no unescaped quotes **Usage**: ```javascript import * as sqlInjection from './utils/sqlInjection.js' if (sqlInjection.isAcceptableParameter(userInput, 1)) { // Safe to use in SQL query } ``` --- ### versionCheck.js **Module**: Node.js version validation utility Validates that the current Node.js version meets the requirements specified in package.json. **Key Functions**: - `checkVersion()` - Check if the current Node.js version meets the required version **Usage**: ```javascript import * as versionCheck from './utils/versionCheck.js' await versionCheck.checkVersion() ``` --- ## CLI Integration Utilities ### btp.js **Module**: `btp` - Library for calling BTP APIs via CLI Provides utilities for interacting with SAP Business Technology Platform (BTP) via the btp CLI. **Key Features**: - BTP CLI version detection - Configuration file parsing - Service instance management - Global account and subaccount targeting **Key Constants**: - `globalAccount`, `subAccount`, `hanaCloudTools`, `applicationStudio`, `hanaPlanName` **Key Functions**: - `getVersion()` - Get btp CLI version - `getInfo()` - Get btp CLI info (configuration, server URL, user) - `getBTPConfig()` - Read central configuration file for BTP CLI **Usage**: ```javascript import * as btp from './utils/btp.js' const version = await btp.getVersion() const info = await btp.getInfo() const config = await btp.getBTPConfig() ``` --- ### cf.js **Module**: `cf` - Library for calling CF APIs via CLI Provides utilities for interacting with Cloud Foundry via the cf CLI. **Key Features**: - CF CLI version detection - Organization and space management - Configuration file parsing (~/.cf/config.json) - Target information retrieval **Key Functions**: - `getVersion()` - Get cf CLI version - `getCFConfig()` - Read central configuration file for CF CLI - `getCFOrg()` / `getCFOrgName()` / `getCFOrgGUID()` - Get target organization details - `getCFSpace()` / `getCFSpaceName()` / `getCFSpaceGUID()` - Get target space details **Usage**: ```javascript import * as cf from './utils/cf.js' const version = await cf.getVersion() const orgName = await cf.getCFOrgName() const spaceName = await cf.getCFSpaceName() ``` --- ### xs.js **Module**: `xs` - Library for calling XSA APIs via CLI Provides utilities for interacting with SAP XS Advanced (XSA) via the xs CLI. **Key Features**: - XSA configuration file parsing (~/.xsconfig) - Organization and space management for XSA - Similar API to cf.js for consistency **Key Functions**: - `getCFConfig()` - Read central configuration file for XSA CLI - `getCFOrg()` / `getCFOrgName()` / `getCFOrgGUID()` - Get target organization details - `getCFSpace()` / `getCFSpaceName()` / `getCFSpaceGUID()` - Get target space details **Usage**: ```javascript import * as xs from './utils/xs.js' const config = await xs.getCFConfig() const orgName = await xs.getCFOrgName() ``` --- ## Database Utilities ### massConvert.js **Module**: Mass conversion utilities for database objects Provides functionality for bulk conversion and export of database objects (tables, views) to various formats. **Key Features**: - Convert multiple tables to HDI artifact formats (.hdbtable) - Convert views to HDI formats - Progress bar visualization - ZIP file generation for exports - Error logging and handling - Support for SQL-based and CDS-based outputs Notes: - `limit` values are validated as positive integers when provided. - View exports in `hdbtable` output are written as `.hdbview` artifacts in the ZIP. - Output folders are created automatically if they do not exist. **Key Functions**: - `hdbtableTablesSQL(prompts, results, wss, db, schema, replacer, zip, logOutput)` - Convert tables to .hdbtable SQL format - `hdbtableViewsSQL(prompts, viewResults, wss, db, schema, replacer, zip, logOutput)` - Convert views to .hdbtable SQL format - `getProcessBarTableOptions(prompts, length)` - Build progress bar options for tables - `getProcessBarViewOptions(prompts, length)` - Build progress bar options for views **Usage**: ```javascript import * as massConvert from './utils/massConvert.js' // Used internally by mass conversion commands ``` --- ## database/ Subfolder The `database/` subfolder contains database-specific client implementations that provide abstraction over different database types. ### index.js **Module**: Abstract database client super class Base class that provides a common interface for all database-specific implementations. **Key Features**: - Factory pattern for database client instantiation - Supports HANA (CDS and direct), PostgreSQL, and SQLite - Connection management (connect/disconnect) - Schema targeting - Profile-based configuration - Credential management **Key Class**: `dbClientClass` **Key Methods**: - `static async getNewClient(prompts)` - Factory method to create the appropriate database client based on profile - `async connect()` - Connect to the target database - `async disconnect()` - Disconnect from the target database - `async connectTargetSchema(schema)` - Connect to a specific schema - `async listTables()` - Abstract method implemented by subclasses - `getDB()` / `setDB(db)` - Getter/setter for database connection - `getPrompts()` - Get current prompts - `schemaCalculation(prompts, optionsCDS)` - Calculate schema name from options **Supported Database Kinds**: - `hana` - SAP HANA via CDS - `postgres` - PostgreSQL via CDS - `sqlite` - SQLite via CDS - `hybrid` / no profile - SAP HANA direct connection (non-CDS) --- ### hanaCDS.js **Module**: Database Client for HANA via CDS Extends `dbClientClass` to provide HANA-specific functionality using SAP CAP/CDS. **Key Features**: - CDS-based querying - Schema calculation and filtering - Table listing with metadata **Key Methods**: - `async listTables()` - Get list of tables from HANA database using CDS query builder --- ### hanaDirect.js **Module**: Database Client for HANA Direct Connection (non-CDS) Extends `dbClientClass` to provide direct HANA connectivity without CDS. **Key Features**: - Direct HANA connection using sap-hdb-promisfied - Raw SQL execution - Independent of CAP/CDS project structure **Key Methods**: - `async connect()` - Connect to HANA database directly - `async disconnect()` - Disconnect from HANA database - `async listTables()` - Get list of tables using direct SQL queries - `async execSQL(query)` - Execute SQL query directly on HANA **Usage**: Automatically selected when no CDS profile is specified. --- ### postgres.js **Module**: Database Client for PostgreSQL via CDS Extends `dbClientClass` to provide PostgreSQL-specific functionality using SAP CAP/CDS. **Key Features**: - PostgreSQL schema management (search_path) - CDS query builder for PostgreSQL - Information schema integration **Key Methods**: - `async listTables()` - Get list of tables from PostgreSQL database using CDS --- ### sqlite.js **Module**: Database Client for SQLite via CDS Extends `dbClientClass` to provide SQLite-specific functionality using SAP CAP/CDS. **Key Features**: - SQLite schema introspection - Lightweight database support - Ideal for local development and testing **Key Methods**: - `async listTables()` - Get list of tables from SQLite database using sqlite_schema --- ## Usage Examples ### Establishing a Database Connection ```javascript import * as base from './utils/base.js' // Set prompts const prompts = { admin: false, schema: 'MYSCHEMA', table: '*', limit: 100 } base.setPrompts(prompts) // Create connection const db = await base.createDBConnection() // Use database connection const version = await dbInspect.getHANAVersion(db) console.log(`HANA Version: ${version.VERSION}`) ``` ### Using Database Client Factory ```javascript import DBClientClass from './utils/database/index.js' // Get appropriate database client based on prompts const prompts = { profile: 'development', // or 'production', 'hybrid', etc. table: 'MY_TABLE', limit: 50 } const dbClient = await DBClientClass.getNewClient(prompts) await dbClient.connect() // List tables const tables = await dbClient.listTables() console.log(tables) // Cleanup await dbClient.disconnect() ``` ### Security: Validating User Input ```javascript import * as sqlInjection from './utils/sqlInjection.js' function executeQuery(userTableName) { // Validate input before using in SQL if (!sqlInjection.isAcceptableParameter(userTableName, 1)) { throw new Error('Invalid table name: possible SQL injection attempt') } // Safe to use in query const query = `SELECT * FROM ${userTableName}` // ... execute query } ``` ### Finding Configuration Files ```javascript import * as conn from './utils/connections.js' // Search for configuration files const defaultEnv = conn.getDefaultEnv() const packageJson = conn.getPackageJSON() const mtaYaml = conn.getMTA() if (defaultEnv) { console.log(`Found default-env.json at: ${defaultEnv}`) } ``` ### Using Terminal UI Components ```javascript import * as base from './utils/base.js' // Start spinner base.startSpinnerInt() // ... perform long operation base.stopSpinnerInt() // Display colored output console.log(base.colors.green('Success!')) console.log(base.colors.red('Error!')) // Display data as table const data = [ { name: 'Table1', rows: 100 }, { name: 'Table2', rows: 200 } ] base.terminal.table(data, base.tableOptions) ``` ### Checking BTP/CF Configuration ```javascript import * as btp from './utils/btp.js' import * as cf from './utils/cf.js' // Check BTP CLI try { const btpVersion = await btp.getVersion() const btpInfo = await btp.getInfo() console.log(`BTP CLI Version: ${btpVersion}`) console.log(`Server URL: ${btpInfo.serverURL}`) } catch (error) { console.log('BTP CLI not configured') } // Check CF CLI try { const cfVersion = await cf.getVersion() const orgName = await cf.getCFOrgName() const spaceName = await cf.getCFSpaceName() console.log(`CF CLI Version: ${cfVersion}`) console.log(`Org: ${orgName}, Space: ${spaceName}`) } catch (error) { console.log('CF CLI not configured') } ``` --- ## Architecture Notes ### Modular Design The utilities are designed to be modular and reusable across the CLI tool. Each module has a specific responsibility and can be used independently or in combination with others. ### Database Abstraction The `database/` subfolder implements a factory pattern with a common abstract base class, allowing the CLI to work with multiple database types (HANA, PostgreSQL, SQLite) through a unified interface. ### Security First SQL injection protection is built into the core utilities and should be used whenever constructing SQL queries with user input. ### Internationalization The base module integrates with SAP's text bundle system for i18n support, allowing the CLI to be localized to different languages. ### Connection Flexibility The connection utilities support multiple methods of providing credentials, from local files to secure cloud-based lookups, giving users flexibility in how they manage sensitive information. --- ## Contributing When adding new utilities to this folder: 1. **Follow the module pattern**: Export modules with ES6 `export` syntax 2. **Document your functions**: Use JSDoc comments for all exported functions 3. **Add to this README**: Update this document with your new utility's description and usage examples 4. **Handle errors gracefully**: Use try-catch blocks and provide meaningful error messages 5. **Security first**: Always validate user input, especially for SQL operations 6. **Test your code**: Ensure your utilities work with different database types and configurations --- ## See Also - [Main Project README](../README.md) - [Changelog](../CHANGELOG.md) - [SAP HANA Developer Guide](https://help.sap.com/docs/HANA_CLOUD_DATABASE) - [SAP CAP Documentation](https://cap.cloud.sap/docs/)