From 366f86687b395c3fabcdca46723acc51f36ea4d1 Mon Sep 17 00:00:00 2001 From: Bo Lu Date: Sun, 8 Dec 2024 23:32:45 +1100 Subject: [PATCH] feat(cal): add booking insertion support --- docs/catalog/cal.md | 32 +++++++++++++++++++--- docs/catalog/index.md | 2 +- wasm-wrappers/fdw/cal_fdw/src/lib.rs | 40 ++++++++++++++++++++++++---- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/docs/catalog/cal.md b/docs/catalog/cal.md index 1ce1d742..c93d3506 100644 --- a/docs/catalog/cal.md +++ b/docs/catalog/cal.md @@ -37,7 +37,7 @@ The Cal.com API uses JSON formatted data, please refer to [Cal.com API docs](htt | Version | Wasm Package URL | Checksum | | ------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -| 0.1.0 | `https://github.com/supabase/wrappers/releases/download/wasm_cal_fdw_v0.1.0/cal_fdw.wasm` | `4b8661caae0e4f7b5a1480ea297cf5681101320712cde914104b82f2b0954003` | +| 0.1.0 | `https://github.com/supabase/wrappers/releases/download/wasm_cal_fdw_v0.1.0/cal_fdw.wasm` | `tbd` | ## Preparation @@ -121,7 +121,7 @@ The Cal.com Wrapper supports data reads from below objects in Cal.com. | -------------| :----: | :----: | :----: | :----: | :------: | | My Profile | ✅ | ❌ | ❌ | ❌ | ❌ | | Event Types | ✅ | ❌ | ❌ | ❌ | ❌ | -| Bookings | ✅ | ❌ | ❌ | ❌ | ❌ | +| Bookings | ✅ | ✅ | ❌ | ❌ | ❌ | | Calendars | ✅ | ❌ | ❌ | ❌ | ❌ | | Schedules | ✅ | ❌ | ❌ | ❌ | ❌ | | Conferencing | ✅ | ❌ | ❌ | ❌ | ❌ | @@ -153,7 +153,8 @@ create foreign table cal.bookings ( ) server cal_server options ( - object 'bookings' + object 'bookings', + rowid_column 'attrs' ); create foreign table cal.calendars ( @@ -188,6 +189,7 @@ create foreign table cal.conferencing ( - All the supported columns are listed above, other columns are not allowd. - The `attrs` is a special column which stores all the object attributes in JSON format, you can extract any attributes needed from it. See more examples below. + - `bookings` table support data insertion, see an example below. ### Foreign table options @@ -250,7 +252,8 @@ create foreign table cal.bookings ( ) server cal_server options ( - object 'bookings' + object 'bookings', + rowid_column 'attrs' ); create foreign table cal.event_types ( @@ -278,3 +281,24 @@ from cal.event_types t cross join json_array_elements((attrs->'eventTypeGroups')::json) etg cross join json_array_elements((etg->'eventTypes')::json) et; ``` + +### Make a booking + +Once we know an event type ID (we can get it from above example, here we suppose it is `123456`), we can make a booking using below SQL. + +``` +insert into cal.bookings(attrs) +values ( + '{ + "start": "2024-12-12T10:30:00.000Z", + "eventTypeId": 123456, + "attendee": { + "name": "Test Name", + "email": "test.name@example.com", + "timeZone": "America/New_York" + } + }'::jsonb +); +``` + +To add more details to the booking, such as `guests` or `metadata`, refer to [Cal.com documentation](https://cal.com/docs/api-reference/v2/bookings/create-a-booking). diff --git a/docs/catalog/index.md b/docs/catalog/index.md index 4a4d9c00..134f6889 100644 --- a/docs/catalog/index.md +++ b/docs/catalog/index.md @@ -13,7 +13,7 @@ hide: | Auth0 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | AWS Cognito | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | BigQuery | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | -| Cal.com | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Cal.com | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | | Calendly | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | ClickHouse | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | | Firebase | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | diff --git a/wasm-wrappers/fdw/cal_fdw/src/lib.rs b/wasm-wrappers/fdw/cal_fdw/src/lib.rs index ab7fcbfb..91574c26 100644 --- a/wasm-wrappers/fdw/cal_fdw/src/lib.rs +++ b/wasm-wrappers/fdw/cal_fdw/src/lib.rs @@ -260,20 +260,50 @@ impl Guest for CalFdw { Ok(()) } - fn begin_modify(_ctx: &Context) -> FdwResult { - Err("modify on foreign table is not supported".to_owned()) + fn begin_modify(ctx: &Context) -> FdwResult { + let this = Self::this_mut(); + let opts = ctx.get_options(OptionsType::Table); + let object = opts.require("object")?; + if object != "bookings" { + return Err("only insert on foreign table 'bookings' is supported".to_owned()); + } + this.object = object; + Ok(()) } - fn insert(_ctx: &Context, _row: &Row) -> FdwResult { + fn insert(_ctx: &Context, row: &Row) -> FdwResult { + let this = Self::this_mut(); + if let Some(cell) = &row.cells()[0] { + match cell { + Cell::Json(body) => { + let url = format!("{}/{}", this.base_url, this.object); + let mut headers = this.headers.clone(); + headers.push(("cal-api-version".to_owned(), "2024-08-13".to_owned())); + let req = http::Request { + method: http::Method::Post, + url, + headers, + body: body.to_owned(), + }; + let resp = http::post(&req)?; + http::error_for_status(&resp) + .map_err(|err| format!("{}: {}", err, resp.body))?; + stats::inc_stats(FDW_NAME, stats::Metric::RowsOut, 1); + } + _ => { + return Err("column type other than JSON is not supported".to_owned()); + } + } + } Ok(()) } fn update(_ctx: &Context, _rowid: Cell, _row: &Row) -> FdwResult { - Ok(()) + Err("update on foreign table is not supported".to_owned()) } fn delete(_ctx: &Context, _rowid: Cell) -> FdwResult { - Ok(()) + Err("delete on foreign table is not supported".to_owned()) } fn end_modify(_ctx: &Context) -> FdwResult {