44 * @fileoverview The `SnowflakeDriver` and related types declaration.
55 */
66
7- import {
8- getEnv ,
9- assertDataSource ,
10- } from '@cubejs-backend/shared' ;
7+ import { assertDataSource , getEnv , } from '@cubejs-backend/shared' ;
118import snowflake , { Column , Connection , RowStatement } from 'snowflake-sdk' ;
129import {
1310 BaseDriver ,
11+ DownloadQueryResultsOptions ,
12+ DownloadQueryResultsResult ,
1413 DownloadTableCSVData ,
14+ DownloadTableMemoryData ,
15+ DriverCapabilities ,
1516 DriverInterface ,
1617 GenericDataBaseType ,
17- TableStructure ,
18- UnloadOptions ,
1918 StreamOptions ,
2019 StreamTableDataWithTypes ,
21- DownloadTableMemoryData ,
22- DownloadQueryResultsResult ,
23- DownloadQueryResultsOptions ,
24- DriverCapabilities ,
20+ TableStructure ,
21+ UnloadOptions ,
2522} from '@cubejs-backend/base-driver' ;
2623import { formatToTimeZone } from 'date-fns-timezone' ;
2724import fs from 'fs/promises' ;
2825import { HydrationMap , HydrationStream } from './HydrationStream' ;
2926
30- // eslint-disable-next-line import/order
31- const util = require ( 'snowflake-sdk/lib/util' ) ;
32-
3327const SUPPORTED_BUCKET_TYPES = [ 's3' , 'gcs' , 'azure' ] ;
3428
35- // TODO Remove when https://github.com/snowflakedb/snowflake-connector-nodejs/pull/158 is resolved
36- util . construct_hostname = ( region : any , account : any ) => {
37- let host ;
38- if ( region === 'us-west-2' ) {
39- region = null ;
40- }
41- if ( account . indexOf ( '.' ) > 0 ) {
42- account = account . substring ( 0 , account . indexOf ( '.' ) ) ;
43- }
44- if ( region ) {
45- host = `${ account } .${ region } .snowflakecomputing.com` ;
46- } else {
47- host = `${ account } .snowflakecomputing.com` ;
48- }
49- return host ;
50- } ;
51-
5229type HydrationConfiguration = {
5330 types : string [ ] , toValue : ( column : Column ) => ( ( value : any ) => any ) | null
5431} ;
@@ -104,11 +81,21 @@ const hydrators: HydrationConfiguration[] = [
10481 }
10582 ) ;
10683 } ,
84+ } ,
85+ {
86+ types : [ 'object' ] , // Workaround for HLL_SNOWFLAKE
87+ toValue : ( ) => ( value ) => {
88+ if ( ! value ) {
89+ return null ;
90+ }
91+
92+ return JSON . stringify ( value ) ;
93+ } ,
10794 }
10895] ;
10996
11097const SnowflakeToGenericType : Record < string , GenericDataBaseType > = {
111- // It's a limitation for now, because anyway we dont work with JSON objects in Cube Store.
98+ // It's a limitation for now, because anyway we don't work with JSON objects in Cube Store.
11299 object : 'HLL_SNOWFLAKE' ,
113100 number : 'decimal' ,
114101 timestamp_ntz : 'timestamp'
@@ -198,9 +185,12 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
198185 return 8 ;
199186 }
200187
188+ /**
189+ * Returns the configurable driver options
190+ * Note: It returns the unprefixed option names.
191+ * In case of using multisources options need to be prefixed manually.
192+ */
201193 public static driverEnvVariables ( ) {
202- // TODO (buntarb): check how this method can/must be used with split
203- // names by the data source.
204194 return [
205195 'CUBEJS_DB_NAME' ,
206196 'CUBEJS_DB_USER' ,
@@ -211,9 +201,11 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
211201 'CUBEJS_DB_SNOWFLAKE_ROLE' ,
212202 'CUBEJS_DB_SNOWFLAKE_CLIENT_SESSION_KEEP_ALIVE' ,
213203 'CUBEJS_DB_SNOWFLAKE_AUTHENTICATOR' ,
204+ 'CUBEJS_DB_SNOWFLAKE_OAUTH_TOKEN_PATH' ,
205+ 'CUBEJS_DB_SNOWFLAKE_HOST' ,
206+ 'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY' ,
214207 'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PATH' ,
215208 'CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PASS' ,
216- 'CUBEJS_DB_SNOWFLAKE_OAUTH_TOKEN_PATH' ,
217209 'CUBEJS_DB_SNOWFLAKE_QUOTED_IDENTIFIERS_IGNORE_CASE' ,
218210 ] ;
219211 }
@@ -257,10 +249,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
257249 privateKey += '\n' ;
258250 }
259251
260- snowflake . configure ( {
261- // TODO: Remove after release of https://github.com/snowflakedb/snowflake-connector-nodejs/pull/912
262- logLevel : 'OFF' as any
263- } ) ;
252+ snowflake . configure ( { logLevel : 'OFF' } ) ;
264253
265254 this . config = {
266255 readOnly : false ,
@@ -416,9 +405,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
416405 this . config . token = await this . readOAuthToken ( ) ;
417406 }
418407
419- const connection = snowflake . createConnection ( this . config ) ;
420-
421- return connection ;
408+ return snowflake . createConnection ( this . config ) ;
422409 }
423410
424411 /**
@@ -475,8 +462,8 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
475462 }
476463 }
477464
478- // eslint-disable-next-line no-return-assign
479- return this . connection = this . initConnection ( ) ;
465+ this . connection = this . initConnection ( ) ;
466+ return this . connection ;
480467 }
481468
482469 /**
@@ -758,7 +745,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
758745 const hydrationMap = this . generateHydrationMap ( stmt . getColumns ( ) ) ;
759746 const types : { name : string , type : string } [ ] =
760747 this . getTypes ( stmt ) ;
761- if ( rows && rows . length && Object . keys ( hydrationMap ) . length ) {
748+ if ( rows ? .length && Object . keys ( hydrationMap ) . length ) {
762749 for ( const row of rows ) {
763750 for ( const [ field , toValue ] of Object . entries ( hydrationMap ) ) {
764751 if ( row . hasOwnProperty ( field ) ) {
@@ -922,6 +909,6 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
922909
923910 public async getTablesQuery ( schemaName : string ) {
924911 const tables = await super . getTablesQuery ( schemaName . toUpperCase ( ) ) ;
925- return tables . map ( t => ( { table_name : t . TABLE_NAME && t . TABLE_NAME . toLowerCase ( ) } ) ) ;
912+ return tables . map ( t => ( { table_name : t . TABLE_NAME ? .toLowerCase ( ) } ) ) ;
926913 }
927914}
0 commit comments