blob: aebf5f14f6371e5c178da857edd2e91483e8e6f6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { QueryResult } from '@druid-toolkit/query';
import FileSaver from 'file-saver';
import * as JSONBig from 'json-bigint-native';
import { copyAndAlert, stringifyValue } from './general';
export function downloadUrl(url: string, filename: string) {
// Create a link and set the URL using `createObjectURL`
const link = document.createElement('a');
link.style.display = 'none';
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
// To make this work on Firefox we need to wait
// a little while before removing it.
setTimeout(() => {
if (!link.parentNode) return;
link.parentNode.removeChild(link);
}, 0);
}
export function formatForFormat(s: null | string | number | Date, format: 'csv' | 'tsv'): string {
// stringify and remove line break
const str = stringifyValue(s).replace(/(?:\r\n|\r|\n)/g, ' ');
if (format === 'csv') {
// csv: single quote => double quote, handle ','
return `"${str.replace(/"/g, '""')}"`;
} else {
// tsv: single quote => double quote, \t => ''
return str.replace(/\t/g, '').replace(/"/g, '""');
}
}
export function downloadFile(text: string, type: string, filename: string): void {
let blobType;
switch (type) {
case 'json':
blobType = 'application/json';
break;
case 'tsv':
blobType = 'text/tab-separated-values';
break;
default:
// csv
blobType = `text/${type}`;
break;
}
const blob = new Blob([text], {
type: blobType,
});
FileSaver.saveAs(blob, filename);
}
function queryResultsToString(queryResult: QueryResult, format: string): string {
let lines: string[] = [];
let separator = '';
if (format === 'csv' || format === 'tsv') {
separator = format === 'csv' ? ',' : '\t';
lines.push(
queryResult.header.map(column => formatForFormat(column.name, format)).join(separator),
);
lines = lines.concat(
queryResult.rows.map(r => r.map(cell => formatForFormat(cell, format)).join(separator)),
);
} else {
// json
lines = queryResult.rows.map(r => {
const outputObject: Record<string, any> = {};
for (let k = 0; k < r.length; k++) {
const newName = queryResult.header[k];
if (newName) {
outputObject[newName.name] = r[k];
}
}
return JSONBig.stringify(outputObject);
});
}
return lines.join('\n');
}
export function downloadQueryResults(
queryResult: QueryResult,
filename: string,
format: string,
): void {
const resultString: string = queryResultsToString(queryResult, format);
downloadFile(resultString, format, filename);
}
export function copyQueryResultsToClipboard(queryResult: QueryResult, format: string): void {
const resultString: string = queryResultsToString(queryResult, format);
copyAndAlert(resultString, 'Query results copied to clipboard');
}