arangodb-cubejs-driver
Version:
Cube.js arangodb driver
159 lines • 5.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArangoDbDriver = void 0;
const base_driver_1 = require("@cubejs-backend/base-driver");
const arangojs_1 = require("arangojs");
const collection_1 = require("arangojs/collection");
const sql_utils_1 = require("./sql-utils");
const ArangoToGenericType = {
number: 'double',
string: 'text',
bool: 'boolean'
};
const sortByKeys = (unordered) => {
const ordered = {};
Object.keys(unordered).sort().forEach((key) => {
ordered[key] = unordered[key];
});
return ordered;
};
class ArangoDbDriver extends base_driver_1.BaseDriver {
/**
* Returns default concurrency value.
* @return {number}
*/
static getDefaultConcurrency() {
return 2;
}
static driverEnvVariables() {
return [
'CUBEJS_DB_URL',
];
}
constructor(config = {}) {
super({
testConnectionTimeout: config.testConnectionTimeout || 60000,
});
const auth = {
username: process.env.CUBEJS_DB_USER,
password: process.env.CUBEJS_DB_PASS,
};
this.config = {
url: process.env.CUBEJS_DB_URL,
databaseName: process.env.CUBEJS_DB_NAME,
auth,
...config
};
this.client = new arangojs_1.Database({
url: this.config.url,
databaseName: this.config.databaseName,
auth: this.config.auth,
// ssl: this.config.ssl
});
}
async testConnection() {
const cursor = await this.client.query({
query: 'RETURN @value',
bindVars: { value: Date.now() }
});
return await cursor.next();
}
async query(_query, _values, _options) {
// console.log(_query, _values, _options);
const aqlQuery = (0, sql_utils_1.sql2aql)(_query, _values);
const cursor = await this.client.query(aqlQuery);
const result = await cursor.all();
await cursor.kill();
return result;
}
async downloadQueryResults(query, values, _options) {
const rows = await this.query(query, values);
const columnTypes = [];
Object.entries(rows[0]).forEach((cols) => {
const [column, value] = cols;
const type = typeof value; // TODO: check float and integer
const genericType = ArangoToGenericType[type];
if (!genericType) {
throw new Error(`Unable to translate type for column "${column}" with type: ${type}`);
}
columnTypes.push({ name: column, type: genericType });
});
return {
rows,
types: columnTypes
};
}
;
async release() {
await this.client.close();
}
readOnly() {
// ArangoDb don't support table creation
return true;
}
async tablesSchema() {
const result = {};
const collections = await this.client.collections();
const schemaName = this.config.databaseName;
let schema = (result[schemaName] || {});
for (const collection of collections) {
const collectionMeta = await collection.get();
if (collectionMeta.type === collection_1.CollectionType.DOCUMENT_COLLECTION) {
schema[collection.name] = await this.tableColumnTypes(collection.name);
}
}
schema = sortByKeys(schema);
result[schemaName] = schema;
return result;
}
async tableColumnTypes(table) {
const columns = [];
// TODO: can optimize by schema registry or swagger json schema
const attrMap = await this.aggrAttrs(table);
const attrNames = Object.keys(attrMap);
for (const attrName of attrNames) {
const attrType = attrMap[attrName];
if (this.toGenericType(attrType)) {
columns.push({ name: attrName, type: attrType, attributes: [] });
}
}
return columns.sort();
}
// public stream?: (table: string, values: unknown[], options: StreamOptions) => Promise<StreamTableData>;
// public unload?: (table: string, options: UnloadOptions) => Promise<DownloadTableCSVData>;
// public isUnloadSupported?: (options: UnloadOptions) => Promise<boolean>;
toGenericType(columnType) {
columnType = columnType.toLowerCase();
if (columnType in ArangoToGenericType) {
return ArangoToGenericType[columnType];
}
return super.toGenericType(columnType);
}
async aggrAttrs(collectionName) {
const cursor = await this.client.query(`
FOR i IN [1]
LET attrMaps = (
FOR doc in ${collectionName}
LET attributes = (
FOR name IN ATTRIBUTES(doc, true)
RETURN {
name: name,
type: TYPENAME(doc[name])
}
)
RETURN ZIP(attributes[*].name, attributes[*].type)
)
RETURN MERGE(attrMaps)`);
let result = { id: 'string' };
if (cursor.hasNext) {
result = {
...result,
...await cursor.next()
};
}
await cursor.kill();
return result;
}
}
exports.ArangoDbDriver = ArangoDbDriver;
//# sourceMappingURL=arangodb-driver.js.map