From b22d622dd93fdb1f958d191b368e27a9817d7b2c Mon Sep 17 00:00:00 2001 From: Tanmai Gopal Date: Wed, 30 Oct 2024 14:22:16 -0700 Subject: [PATCH] Adds support for bigint. Cleans up index and functions to start from scratch --- connector-definition/template/.gitignore | 2 + connector-definition/template/functions.ts | 265 +-------------------- connector-definition/template/index.ts | 7 +- ndc-duckduckapi/package-lock.json | 20 -- ndc-duckduckapi/package.json | 1 - ndc-duckduckapi/src/constants.ts | 54 ++++- ndc-duckduckapi/src/generate-config.ts | 2 +- 7 files changed, 60 insertions(+), 291 deletions(-) diff --git a/connector-definition/template/.gitignore b/connector-definition/template/.gitignore index 6362c8c..23f293a 100644 --- a/connector-definition/template/.gitignore +++ b/connector-definition/template/.gitignore @@ -1,3 +1,5 @@ node_modules/ duck.db duck.db.wal +github.index.ts +github.functions.ts diff --git a/connector-definition/template/functions.ts b/connector-definition/template/functions.ts index c78ef25..92d171b 100644 --- a/connector-definition/template/functions.ts +++ b/connector-definition/template/functions.ts @@ -1,266 +1,3 @@ import { JSONValue } from "@hasura/ndc-lambda-sdk"; import { GMail, GoogleCalendar } from "@hasura/ndc-duckduckapi/services"; -import { getOAuthCredentialsFromHeader } from "@hasura/ndc-duckduckapi"; -import { getDB } from "@hasura/ndc-duckduckapi"; - -/***********************************************************************************/ -/************************** BUILT-IN EXAMPLES **************************************/ -/***********************************************************************************/ - -/* To add more built in examples, check out other services at @hasura/ndc-duckduckapi/services */ -const calendarLoaderState = { - state: "Stopped", -}; -let syncManager; - -(async () => { - try { - console.log( - "Trying to initialize calendar loader in case credentials are already available" - ); - const calendarSyncManager = await GoogleCalendar.SyncManager.create( - calendarLoaderState, - 1 - ); - await calendarSyncManager.initialize(); - } catch (error) { - calendarLoaderState.state = `Stopped`; - console.error(error); - } -})(); - -/** - * $ddn.jobs.calendar-loader.init - */ -export async function __dda_calendar_loader_init( - headers: JSONValue -): Promise { - if (calendarLoaderState.state == "Running") { - return calendarLoaderState.state; - } - - let credentials; - credentials = getOAuthCredentialsFromHeader(headers); - - if ( - !credentials || - !credentials["google-calendar"] || - !credentials["google-calendar"].access_token - ) { - console.log(credentials); - calendarLoaderState.state = `Error in getting the google-calendar oauth credentials. Login to google-calendar?`; - return calendarLoaderState.state; - } - - syncManager = await GoogleCalendar.SyncManager.create( - calendarLoaderState, - 1, // sync every minute - credentials["google-calendar"] - ); - - return await syncManager.initialize(); -} -/** - * $ddn.jobs.calendar-loader.status - * - * @readonly - * */ -export function __dda_calendar_loader_status(): string { - return calendarLoaderState.state; -} - -/** - * This is a function to create an event on your google calendar - */ -export async function createCalendarEvent( - headers: JSONValue, - summary: string, - startDateTime: Date, - endDateTime: Date, - description?: string, - attendees?: string[], - timeZone?: string, - location?: string -): Promise<{ success: boolean; message: string }> { - let credentials; - credentials = getOAuthCredentialsFromHeader(headers); - - if ( - !credentials || - !credentials["google-calendar"] || - !credentials["google-calendar"].access_token - ) { - console.log(credentials); - return { - success: false, - message: `Error in getting the google-calendar oauth credentials. Login to google-calendar?`, - }; - } - - const event = await GoogleCalendar.CreateCalendarEvent( - credentials["google-calendar"], - summary, - description, - startDateTime, - endDateTime, - attendees, - timeZone, - location - ); - - if (event.status === "error") { - return { success: false, message: `Error creating event: ${event.error}` }; - } else { - return { success: true, message: `Event created successfully: ${event}` }; - } -} - -/*********************************************************************************************** - * GMAIL LOADER - ***********************************************************************************************/ -/* To add more built in examples, check out other services at @hasura/ndc-duckduckapi/services */ -const gmailLoaderState = { - state: "Stopped", -}; - -(async () => { - try { - console.log( - "Trying to initialize gmail loader in case credentials are already available" - ); - const gmailSyncManager = await GMail.SyncManager.create( - gmailLoaderState, - 1 - ); - await gmailSyncManager.initialize(); - } catch (error) { - gmailLoaderState.state = `Stopped`; - console.error(error); - } -})(); - -/** - * $ddn.jobs.gmail-loader.init - */ -export async function __dda_gmail_loader_init( - headers: JSONValue -): Promise { - if (gmailLoaderState.state == "Running") { - return gmailLoaderState.state; - } - - let credentials; - credentials = getOAuthCredentialsFromHeader(headers); - - if ( - !credentials || - !credentials["google-gmail"] || - !credentials["google-gmail"].access_token - ) { - console.log(credentials); - gmailLoaderState.state = `Error in getting the GMail oauth credentials. Login to google-gmail?`; - return gmailLoaderState.state; - } - - const syncManager = await GMail.SyncManager.create( - gmailLoaderState, - 1, // sync every minute - credentials["google-gmail"] - ); - - return await syncManager.initialize(); -} - -/** - * $ddn.jobs.gmail-loader.status - * - * @readonly - * */ -export function __dda_gmail_loader_status(): string { - return gmailLoaderState.state; -} - -/**********************************************************************************************/ -/*************************** Add your own loader ********************************************/ -/**********************************************************************************************/ - -const myLoaderState = { - state: "This is an unimplemented loader. Edit it in functions.ts.", -}; - -/** - * This is the loader function which will start loading data into duckdb. - * // Mark your functions with this annotation to see it in the console - * // Replace my-loader to create your own unique name, eg: my-saas-loader, and to group it with the right job status method. - * $ddn.jobs.my-loader.init - */ -export async function __dda_my_loader_init( - headers: JSONValue -): Promise { - // If the loader is already running - if (myLoaderState.state === "running") { - return myLoaderState.state; - } - - // Get the oauth credentials from the header - let credentials; - credentials = getOAuthCredentialsFromHeader(headers); - console.log(credentials); - - // If the credentials are not found, return an error and update the status so that the user can login - if ( - !credentials || - !credentials["my-service"] || - !credentials["my-service"].access_token - ) { - myLoaderState.state = `Error in getting the my-service oauth credentials. Login to my-service?`; - return myLoaderState.state; - } - - /* Implement the logic to load data from my-service into duckdb - - 1. Use the credentials to do a quick syncronous test if access to my-service is successful - 2. If yes, then update your loader state to running and initialize the loader and make it run asynchronously - 3. Return the loader state - - */ - - return myLoaderState.state; -} - -/** - * Function that gives you the current status of the loader job. - * // Mark your functions with this annotation to see it in the console - * // Replace sample-loader to create your own unique name, eg: my-saas-loader, and to group it with the right job init method. - * $ddn.jobs.my-loader.status - * - * @readonly - * */ -export function __dda_my_loader_status(): string { - return myLoaderState.state; -} - -/*******************************************************************************************/ -/* Some other examples of custom actions you want to provide or APIs you want to wrap over */ -/*******************************************************************************************/ - -/** @readonly */ -export function testCalendar(headers: JSONValue): JSONValue { - return new JSONValue({ - success: true, - }); -} - -/** @readonly */ -export function hello(name: string, year: number): string { - return `Helloooo ${name}, welcome to ${year}`; -} - -/** @readonly */ -export function bye(name: string): string { - return `Bye ${name}!`; -} - -export async function sendEmail(email: string): Promise { - return `Email sent to: ${email}!`; -} +import { getOAuthCredentialsFromHeader, getDB, transaction } from "@hasura/ndc-duckduckapi"; diff --git a/connector-definition/template/index.ts b/connector-definition/template/index.ts index 37f27bf..8b37049 100644 --- a/connector-definition/template/index.ts +++ b/connector-definition/template/index.ts @@ -2,17 +2,16 @@ import { start } from "@hasura/ndc-duckduckapi"; import { makeConnector, duckduckapi } from "@hasura/ndc-duckduckapi"; import * as path from "path"; -import { GoogleCalendar, GMail} from "@hasura/ndc-duckduckapi/services"; const connectorConfig: duckduckapi = { dbSchema: ` -- Add your SQL schema here. -- This SQL will be run on startup every time. - -- CREATE TABLE SAAS_TABLE_NAME (.....); + -- CREATE TABLE TABLE_NAME (.....); + SELECT 1; - ` + GoogleCalendar.Schema - + GMail.Schema, + `, functionsFilePath: path.resolve(__dirname, "./functions.ts"), }; diff --git a/ndc-duckduckapi/package-lock.json b/ndc-duckduckapi/package-lock.json index 00dd668..f61d322 100644 --- a/ndc-duckduckapi/package-lock.json +++ b/ndc-duckduckapi/package-lock.json @@ -26,7 +26,6 @@ "@types/fs-extra": "^11.0.4", "@types/jest": "^29.5.14", "@types/node": "^22.8.4", - "heapdump": "^0.3.15", "jest": "^29.7.0", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", @@ -4574,19 +4573,6 @@ "node": ">= 0.4" } }, - "node_modules/heapdump": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.15.tgz", - "integrity": "sha512-n8aSFscI9r3gfhOcAECAtXFaQ1uy4QSke6bnaL+iymYZ/dWs9cqDqHM+rALfsHUwukUbxsdlECZ0pKmJdQ/4OA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "nan": "^2.13.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/help-me": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", @@ -5975,12 +5961,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/nan": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", - "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", diff --git a/ndc-duckduckapi/package.json b/ndc-duckduckapi/package.json index 07afa0e..1729dce 100644 --- a/ndc-duckduckapi/package.json +++ b/ndc-duckduckapi/package.json @@ -40,7 +40,6 @@ "@types/fs-extra": "^11.0.4", "@types/jest": "^29.5.14", "@types/node": "^22.8.4", - "heapdump": "^0.3.15", "jest": "^29.7.0", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", diff --git a/ndc-duckduckapi/src/constants.ts b/ndc-duckduckapi/src/constants.ts index d236422..900403c 100644 --- a/ndc-duckduckapi/src/constants.ts +++ b/ndc-duckduckapi/src/constants.ts @@ -18,7 +18,59 @@ export const CAPABILITIES_RESPONSE: Capabilities = { }; export const MAX_32_INT: number = 2147483647; export const SCALAR_TYPES: { [key: string]: ScalarType } = { - Int: { + BigInt: { + representation: { + type: "biginteger" + }, + aggregate_functions: { + // sum: { + // result_type: { + // type: "named", + // name: "Int" + // } + // } + }, + comparison_operators: { + _eq: { + type: "equal", + }, + _gt: { + type: "custom", + argument_type: { + type: "named", + name: "Int", + }, + }, + _lt: { + type: "custom", + argument_type: { + type: "named", + name: "Int", + }, + }, + _gte: { + type: "custom", + argument_type: { + type: "named", + name: "Int", + }, + }, + _lte: { + type: "custom", + argument_type: { + type: "named", + name: "Int", + }, + }, + _neq: { + type: "custom", + argument_type: { + type: "named", + name: "Int", + }, + }, + }, + }, Int: { aggregate_functions: { // sum: { // result_type: { diff --git a/ndc-duckduckapi/src/generate-config.ts b/ndc-duckduckapi/src/generate-config.ts index 8e75979..3fbb9b8 100644 --- a/ndc-duckduckapi/src/generate-config.ts +++ b/ndc-duckduckapi/src/generate-config.ts @@ -18,7 +18,7 @@ if ( const determineType = (t: string): string => { switch (t) { case "BIGINT": - return "Int"; + return "BigInt"; case "BIT": return "String"; case "BOOLEAN":