UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

145 lines (138 loc) 7.21 kB
import { Messages } from "@salesforce/core"; import { Flags, requiredOrgFlagWithDeprecations, SfCommand } from "@salesforce/sf-plugins-core"; import { dataCloudSqlQuery, listAvailableDataCloudQueries, loadDataCloudQueryFromFile, saveDataCloudQueryToFile } from "../../../common/utils/dataCloudUtils.js"; import { generateCsvFile, generateReportPath } from "../../../common/utils/filesUtils.js"; import { uxLog } from "../../../common/utils/index.js"; import { prompts } from "../../../common/utils/prompts.js"; import c from "chalk"; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class DataCloudSqlQuery extends SfCommand { static title = 'Execute a SQL query on Data Cloud'; static description = ` ## Command Behavior **Executes a SQL query against Salesforce Data Cloud and exports the results.** This command lets you run ad-hoc or predefined SQL queries on Data Cloud objects, view the results in the CLI, and export them for further analysis. Key functionalities: - **Query input:** Accepts inline SQL via \`-q\`, a predefined saved query name, or an interactive prompt when no query is provided. - **Test shortcut:** \`-q test\` runs a sample query on \`ssot__Account__dlm\` (sorted by created date, limited to 5000 rows). - **Export:** Generates CSV and XLSX reports for the returned rows with auto-generated filenames (override with \`--outputfile\`). - **Logging:** Prints a JSON summary (excluding full records) and supports debug output via \`--debug\`. - **Org targeting:** Works with the provided or default org connection; respects websocket and skipauth flags. <details markdown="1"> <summary>Technical explanations</summary> The command's technical implementation involves: - **Query resolution:** - If \`-q\` is provided, it is used directly (with a special \`test\` branch loading a canned query). - If absent, prompts the user to select from predefined queries on disk (via \`listAvailableDataCloudQueries\` / \`loadDataCloudQueryFromFile\`), or enter a custom query. Custom queries can be optionally saved locally (\`saveDataCloudQueryToFile\`). - **Execution:** Calls \`dataCloudSqlQuery\` with the resolved SQL against the target org connection. - **Output handling:** Logs the full result JSON to the terminal; emits a sanitized summary to \`uxLog\` (records removed for readability). - **File generation:** Uses \`generateReportPath\` to build the output path and \`generateCsvFile\` to produce CSV/XLSX exports with a \`DataCloud Sql Query Results\` title. - **CLI UX:** Employs \`prompts\` for interactive selection/input and \`uxLog\` for consistent colored logging with chalk. </details> `; static examples = [ '$ sf hardis:datacloud:sql-query', '$ sf hardis:datacloud:sql-query -q "SELECT ssot__Name__c, ssot__CreatedDate__c FROM ssot__Account__dlm LIMIT 10"', '$ sf hardis:datacloud:sql-query -q test' ]; /* jscpd:ignore-start */ static flags = { query: Flags.string({ char: 'q', description: 'Data Cloud query string', }), outputfile: Flags.string({ char: 'f', description: 'Force the path and name of output report file. Must end with .csv', }), debug: Flags.boolean({ char: 'd', default: false, description: messages.getMessage('debugMode'), }), websocket: Flags.string({ description: messages.getMessage('websocket'), }), skipauth: Flags.boolean({ description: 'Skip authentication check when a default username is required', }), 'target-org': requiredOrgFlagWithDeprecations, }; static requiresProject = false; debugMode = false; queryString = ''; outputFile; outputFilesRes = {}; /* jscpd:ignore-end */ async run() { const { flags } = await this.parse(DataCloudSqlQuery); this.queryString = flags.query; this.outputFile = flags.outputfile || null; this.debugMode = flags.debug || false; const conn = flags['target-org'].getConnection(); if (this.queryString === 'test') { this.queryString = ` SELECT ssot__Name__c, ssot__CreatedDate__c FROM ssot__Account__dlm ORDER BY ssot__CreatedDate__c DESC LIMIT 5000; `; } if (this.queryString === '' || this.queryString == null) { const availableQueries = await listAvailableDataCloudQueries(); if (availableQueries.length > 0) { const queryChoicePromptRes = await prompts({ type: 'select', message: 'Please select a predefined Data Cloud SQL query or choose "Custom Query" to enter your own:', description: 'Available predefined queries', choices: [...availableQueries.map(q => ({ title: q, value: q })), { title: 'Custom Query', value: 'custom' }], }); if (queryChoicePromptRes.value !== 'custom') { this.queryString = await loadDataCloudQueryFromFile(queryChoicePromptRes.value); } } } if (this.queryString === '' || this.queryString == null) { const customQueryPromptRes = await prompts({ type: 'text', message: 'Please enter your Data Cloud SQL query:', description: 'Custom Data Cloud SQL query', }); this.queryString = customQueryPromptRes.value; // Prompt user if he wants to save the query const saveQueryPromptRes = await prompts({ type: 'confirm', message: 'Do you want to save this query for future use?', description: 'Save Data Cloud SQL query in local files', initial: false, }); if (saveQueryPromptRes.value) { const saveQueryNamePromptRes = await prompts({ type: 'text', message: 'Enter a name for the saved query:', description: 'Name of the Data Cloud SQL query to save', }); if (saveQueryNamePromptRes.value) { await saveDataCloudQueryToFile(saveQueryNamePromptRes.value.trim(), this.queryString); } } } uxLog("action", this, c.cyan('Executing Data Cloud SQL query...')); const result = await dataCloudSqlQuery(this.queryString, conn, {}); this.logJson(result); // Output results (except records) const resultCopy = { ...result }; resultCopy.records = [{ removedFromDisplay: true }]; uxLog("other", this, JSON.stringify(resultCopy, null, 2)); // Generate output CSV file this.outputFile = await generateReportPath('datacloud-sql-query', this.outputFile); this.outputFilesRes = await generateCsvFile(result.records, this.outputFile, { fileTitle: 'DataCloud Sql Query Results' }); return { sqlResult: JSON.parse(JSON.stringify(result)) }; } } //# sourceMappingURL=sql-query.js.map