diff --git a/.github/workflows/build-publish-rh-image.yml b/.github/workflows/build-publish-rh-image.yml index f9c6fd139c..7d8dc39e32 100644 --- a/.github/workflows/build-publish-rh-image.yml +++ b/.github/workflows/build-publish-rh-image.yml @@ -64,7 +64,7 @@ jobs: platforms: linux/amd64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust secrets: | rh_username=${{ secrets.RH_USERNAME }} rh_password=${{ secrets.RH_PASSWORD }} @@ -81,7 +81,7 @@ jobs: platforms: linux/arm64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust secrets: | rh_username=${{ secrets.RH_USERNAME }} rh_password=${{ secrets.RH_PASSWORD }} diff --git a/.github/workflows/build_windows_worker_.yml b/.github/workflows/build_windows_worker_.yml index 1761646d8f..5ed0bc3820 100644 --- a/.github/workflows/build_windows_worker_.yml +++ b/.github/workflows/build_windows_worker_.yml @@ -45,7 +45,7 @@ jobs: $env:OPENSSL_DIR="${Env:VCPKG_INSTALLATION_ROOT}\installed\x64-windows-static" mkdir frontend/build && cd backend New-Item -Path . -Name "windmill-api/openapi-deref.yaml" -ItemType "File" -Force - cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust - name: Rename binary with corresponding architecture run: | diff --git a/.github/workflows/docker-image-rpi4.yml b/.github/workflows/docker-image-rpi4.yml index 5034138761..869787a4aa 100644 --- a/.github/workflows/docker-image-rpi4.yml +++ b/.github/workflows/docker-image-rpi4.yml @@ -67,7 +67,7 @@ jobs: platforms: linux/amd64,linux/arm64 push: true build-args: | - features=embedding,parquet,openidconnect,deno_core,license,http_trigger,zip,oauth2,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + features=embedding,parquet,openidconnect,deno_core,license,http_trigger,zip,oauth2,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev ${{ steps.meta-public.outputs.tags }} diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 8361c07a59..afd1b6f03b 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -86,7 +86,7 @@ jobs: platforms: linux/amd64,linux/arm64 push: true build-args: | - features=embedding,parquet,openidconnect,jemalloc,deno_core,license,http_trigger,zip,oauth2,dind,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + features=embedding,parquet,openidconnect,jemalloc,deno_core,license,http_trigger,zip,oauth2,dind,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DEV_SHA }} ${{ steps.meta-public.outputs.tags }} @@ -149,7 +149,7 @@ jobs: platforms: linux/amd64,linux/arm64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,otel,dind,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,otel,dind,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }} ${{ steps.meta-ee-public.outputs.tags }} @@ -211,7 +211,7 @@ jobs: platforms: linux/amd64 push: true build-args: | - features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,otel,dind,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + features=enterprise,enterprise_saml,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,otel,dind,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust PYTHON_IMAGE=python:3.12.2-slim-bookworm tags: | ${{ steps.meta-ee-public-py312.outputs.tags }} diff --git a/.github/workflows/publish_windows_worker.yml b/.github/workflows/publish_windows_worker.yml index 324c762b19..e6854020be 100644 --- a/.github/workflows/publish_windows_worker.yml +++ b/.github/workflows/publish_windows_worker.yml @@ -47,7 +47,7 @@ jobs: $env:OPENSSL_DIR="${Env:VCPKG_INSTALLATION_ROOT}\installed\x64-windows-static" mkdir frontend/build && cd backend New-Item -Path . -Name "windmill-api/openapi-deref.yaml" -ItemType "File" -Force - cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,websocket,python,smtp,csharp,static_frontend,rust + cargo build --release --features=enterprise,stripe,embedding,parquet,prometheus,openidconnect,cloud,jemalloc,tantivy,deno_core,license,http_trigger,zip,oauth2,kafka,nats,php,mysql,mssql,bigquery,oracledb,websocket,python,smtp,csharp,static_frontend,rust - name: Rename binary with corresponding architecture run: | diff --git a/backend/.sqlx/query-00a16dbe1729d530f136279471fa3d89ca7f1a88a48fcf0b1ac07144924c1707.json b/backend/.sqlx/query-00a16dbe1729d530f136279471fa3d89ca7f1a88a48fcf0b1ac07144924c1707.json deleted file mode 100644 index 9c581eae99..0000000000 --- a/backend/.sqlx/query-00a16dbe1729d530f136279471fa3d89ca7f1a88a48fcf0b1ac07144924c1707.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT value as \"value: sqlx::types::Json>\" FROM flow_version WHERE id = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "value: sqlx::types::Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false - ] - }, - "hash": "00a16dbe1729d530f136279471fa3d89ca7f1a88a48fcf0b1ac07144924c1707" -} diff --git a/backend/.sqlx/query-0722f461da9edb169c3c73423440eaa3e1b9f2ca3b7033bd7ed978a3b4ddf3fc.json b/backend/.sqlx/query-0722f461da9edb169c3c73423440eaa3e1b9f2ca3b7033bd7ed978a3b4ddf3fc.json deleted file mode 100644 index 86b1a7790a..0000000000 --- a/backend/.sqlx/query-0722f461da9edb169c3c73423440eaa3e1b9f2ca3b7033bd7ed978a3b4ddf3fc.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT raw_flow AS \"raw_flow!: Json>\"\n FROM job WHERE id = $1 AND workspace_id = $2 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "raw_flow!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Text" - ] - }, - "nullable": [ - true - ] - }, - "hash": "0722f461da9edb169c3c73423440eaa3e1b9f2ca3b7033bd7ed978a3b4ddf3fc" -} diff --git a/backend/.sqlx/query-0ad36c1598ff4ece0c325eaeb9a9177a87e1accd192402e21db5ae09c3498ab0.json b/backend/.sqlx/query-0ad36c1598ff4ece0c325eaeb9a9177a87e1accd192402e21db5ae09c3498ab0.json index 1d1592f052..2d06bac0c9 100644 --- a/backend/.sqlx/query-0ad36c1598ff4ece0c325eaeb9a9177a87e1accd192402e21db5ae09c3498ab0.json +++ b/backend/.sqlx/query-0ad36c1598ff4ece0c325eaeb9a9177a87e1accd192402e21db5ae09c3498ab0.json @@ -76,7 +76,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-0bf123446bebbc357c58a53a9319f4954dbf3225e91cbe999e5b264c1a747664.json b/backend/.sqlx/query-0bf123446bebbc357c58a53a9319f4954dbf3225e91cbe999e5b264c1a747664.json index 2ae7c8df90..a7c52db593 100644 --- a/backend/.sqlx/query-0bf123446bebbc357c58a53a9319f4954dbf3225e91cbe999e5b264c1a747664.json +++ b/backend/.sqlx/query-0bf123446bebbc357c58a53a9319f4954dbf3225e91cbe999e5b264c1a747664.json @@ -38,7 +38,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-10cd655d3d2916721b530c7faa7652fb8fae25383b58f6b9e8dc431b76947315.json b/backend/.sqlx/query-10cd655d3d2916721b530c7faa7652fb8fae25383b58f6b9e8dc431b76947315.json deleted file mode 100644 index 4d9c9a8e8c..0000000000 --- a/backend/.sqlx/query-10cd655d3d2916721b530c7faa7652fb8fae25383b58f6b9e8dc431b76947315.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT value AS \"value!: Json>\"\n FROM flow_version WHERE id = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "value!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false - ] - }, - "hash": "10cd655d3d2916721b530c7faa7652fb8fae25383b58f6b9e8dc431b76947315" -} diff --git a/backend/.sqlx/query-1289e7278d2a289bfaa53f00e0b6dceb195df0fb43a8ac03bc8b35939fc941dd.json b/backend/.sqlx/query-1289e7278d2a289bfaa53f00e0b6dceb195df0fb43a8ac03bc8b35939fc941dd.json deleted file mode 100644 index fc01ba95e3..0000000000 --- a/backend/.sqlx/query-1289e7278d2a289bfaa53f00e0b6dceb195df0fb43a8ac03bc8b35939fc941dd.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM workspace LIMIT $1 OFFSET $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "name", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "owner", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "deleted", - "type_info": "Bool" - }, - { - "ordinal": 4, - "name": "premium", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - }, - "nullable": [ - false, - false, - false, - false, - false - ] - }, - "hash": "1289e7278d2a289bfaa53f00e0b6dceb195df0fb43a8ac03bc8b35939fc941dd" -} diff --git a/backend/.sqlx/query-21cd7cbab7799baf5c381427d9b373c0bb144715eddfe54e3b01f6049d7966a2.json b/backend/.sqlx/query-21cd7cbab7799baf5c381427d9b373c0bb144715eddfe54e3b01f6049d7966a2.json deleted file mode 100644 index 2b438c849a..0000000000 --- a/backend/.sqlx/query-21cd7cbab7799baf5c381427d9b373c0bb144715eddfe54e3b01f6049d7966a2.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT workspace.id, workspace.name, usr.username\n FROM workspace, usr WHERE usr.workspace_id = workspace.id AND usr.email = $1 AND deleted = false", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "name", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "username", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "21cd7cbab7799baf5c381427d9b373c0bb144715eddfe54e3b01f6049d7966a2" -} diff --git a/backend/.sqlx/query-2b2ee874dbd90beec26713d2effdc5d011d9f1091a13761642d064220add7b41.json b/backend/.sqlx/query-2b2ee874dbd90beec26713d2effdc5d011d9f1091a13761642d064220add7b41.json deleted file mode 100644 index cc91b1795a..0000000000 --- a/backend/.sqlx/query-2b2ee874dbd90beec26713d2effdc5d011d9f1091a13761642d064220add7b41.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT flow.versions[array_upper(flow.versions, 1)] AS \"version!: i64\"\n FROM flow WHERE path = $1 AND workspace_id = $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "version!: i64", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "2b2ee874dbd90beec26713d2effdc5d011d9f1091a13761642d064220add7b41" -} diff --git a/backend/.sqlx/query-337f31c2172194cd594042c561998a03f751b246c40daf056fced0fd91f6dd73.json b/backend/.sqlx/query-337f31c2172194cd594042c561998a03f751b246c40daf056fced0fd91f6dd73.json index 4e6dccc00a..075a898e29 100644 --- a/backend/.sqlx/query-337f31c2172194cd594042c561998a03f751b246c40daf056fced0fd91f6dd73.json +++ b/backend/.sqlx/query-337f31c2172194cd594042c561998a03f751b246c40daf056fced0fd91f6dd73.json @@ -62,7 +62,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-4ab6d6584029aacdc1e39fcbf39767a49717246179c0652b10aac9078b4e2ae7.json b/backend/.sqlx/query-4ab6d6584029aacdc1e39fcbf39767a49717246179c0652b10aac9078b4e2ae7.json deleted file mode 100644 index 01c2a70c95..0000000000 --- a/backend/.sqlx/query-4ab6d6584029aacdc1e39fcbf39767a49717246179c0652b10aac9078b4e2ae7.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT usr.email, usage.executions\n FROM usr\n , LATERAL (\n SELECT COALESCE(SUM(duration_ms + 1000)/1000 , 0)::BIGINT executions\n FROM completed_job\n WHERE workspace_id = $1\n AND job_kind NOT IN ('flow', 'flowpreview')\n AND email = usr.email\n AND now() - '1 week'::interval < created_at \n ) usage\n WHERE workspace_id = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "executions", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - null - ] - }, - "hash": "4ab6d6584029aacdc1e39fcbf39767a49717246179c0652b10aac9078b4e2ae7" -} diff --git a/backend/.sqlx/query-61c29d684e8e683e839a6d7210b3b9b96854e5bfd752e45922c358c42ebea0c4.json b/backend/.sqlx/query-61c29d684e8e683e839a6d7210b3b9b96854e5bfd752e45922c358c42ebea0c4.json index 5698ec9939..6354dae16b 100644 --- a/backend/.sqlx/query-61c29d684e8e683e839a6d7210b3b9b96854e5bfd752e45922c358c42ebea0c4.json +++ b/backend/.sqlx/query-61c29d684e8e683e839a6d7210b3b9b96854e5bfd752e45922c358c42ebea0c4.json @@ -58,7 +58,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-661f472ff3860983322162420457f5033b9c9afc344d9c3e385ba20a3ad2197a.json b/backend/.sqlx/query-661f472ff3860983322162420457f5033b9c9afc344d9c3e385ba20a3ad2197a.json index 75b8108281..1fa370e682 100644 --- a/backend/.sqlx/query-661f472ff3860983322162420457f5033b9c9afc344d9c3e385ba20a3ad2197a.json +++ b/backend/.sqlx/query-661f472ff3860983322162420457f5033b9c9afc344d9c3e385ba20a3ad2197a.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-6f4817fad2739a11d89b6704edf62c3c267ca336a8b6bec5b29d4409030ed561.json b/backend/.sqlx/query-6f4817fad2739a11d89b6704edf62c3c267ca336a8b6bec5b29d4409030ed561.json index 7e00cac319..3e2098f170 100644 --- a/backend/.sqlx/query-6f4817fad2739a11d89b6704edf62c3c267ca336a8b6bec5b29d4409030ed561.json +++ b/backend/.sqlx/query-6f4817fad2739a11d89b6704edf62c3c267ca336a8b6bec5b29d4409030ed561.json @@ -56,7 +56,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-75451b6d48e4c26812ae64981d0d968b8fb0bf4374a2fccc167fa879bad7078f.json b/backend/.sqlx/query-75451b6d48e4c26812ae64981d0d968b8fb0bf4374a2fccc167fa879bad7078f.json index 19b8734576..287284b86b 100644 --- a/backend/.sqlx/query-75451b6d48e4c26812ae64981d0d968b8fb0bf4374a2fccc167fa879bad7078f.json +++ b/backend/.sqlx/query-75451b6d48e4c26812ae64981d0d968b8fb0bf4374a2fccc167fa879bad7078f.json @@ -58,7 +58,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json b/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json index 7cbd85f23b..2179199223 100644 --- a/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json +++ b/backend/.sqlx/query-804fc11e35f4afc0db194b6fe2594f91df7e588d4d2431bc85f4d8734920c8bf.json @@ -31,7 +31,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-85085cdc08c262c4750566a0a0b9754017b890ea8c1161a5892b6c29e663ee0e.json b/backend/.sqlx/query-85085cdc08c262c4750566a0a0b9754017b890ea8c1161a5892b6c29e663ee0e.json deleted file mode 100644 index 7c86fa85a7..0000000000 --- a/backend/.sqlx/query-85085cdc08c262c4750566a0a0b9754017b890ea8c1161a5892b6c29e663ee0e.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT value AS \"value!: Json>\"\n FROM flow_version_lite WHERE id = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "value!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true - ] - }, - "hash": "85085cdc08c262c4750566a0a0b9754017b890ea8c1161a5892b6c29e663ee0e" -} diff --git a/backend/.sqlx/query-89de3ff8ab32e545efcbcda05f994cb1a32c4991cbd25046282d34272587d2de.json b/backend/.sqlx/query-89de3ff8ab32e545efcbcda05f994cb1a32c4991cbd25046282d34272587d2de.json index 56dc319186..d90a9646de 100644 --- a/backend/.sqlx/query-89de3ff8ab32e545efcbcda05f994cb1a32c4991cbd25046282d34272587d2de.json +++ b/backend/.sqlx/query-89de3ff8ab32e545efcbcda05f994cb1a32c4991cbd25046282d34272587d2de.json @@ -58,7 +58,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-8c15ea27be82665fe74a4be3182a5049fa937e30b4115caf0ba8d61d34f2089a.json b/backend/.sqlx/query-8c15ea27be82665fe74a4be3182a5049fa937e30b4115caf0ba8d61d34f2089a.json deleted file mode 100644 index 9b20861537..0000000000 --- a/backend/.sqlx/query-8c15ea27be82665fe74a4be3182a5049fa937e30b4115caf0ba8d61d34f2089a.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE queue SET running = false, started_at = null\n WHERE last_ping < now() - ($1 || ' seconds')::interval\n AND running = true AND job_kind NOT IN ('flow', 'flowpreview', 'singlescriptflow') AND same_worker = false RETURNING id, workspace_id, last_ping", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Uuid" - }, - { - "ordinal": 1, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "last_ping", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - true - ] - }, - "hash": "8c15ea27be82665fe74a4be3182a5049fa937e30b4115caf0ba8d61d34f2089a" -} diff --git a/backend/.sqlx/query-92e60af0d3ae8c73d74ae68d70e20ae18f79cc84626097b766307cd42722baa3.json b/backend/.sqlx/query-92e60af0d3ae8c73d74ae68d70e20ae18f79cc84626097b766307cd42722baa3.json index acc6769652..ec393b4218 100644 --- a/backend/.sqlx/query-92e60af0d3ae8c73d74ae68d70e20ae18f79cc84626097b766307cd42722baa3.json +++ b/backend/.sqlx/query-92e60af0d3ae8c73d74ae68d70e20ae18f79cc84626097b766307cd42722baa3.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-94a38b83d59f8c010bd96852bf57163476791448201bdd22a9e463a4116b9582.json b/backend/.sqlx/query-94a38b83d59f8c010bd96852bf57163476791448201bdd22a9e463a4116b9582.json deleted file mode 100644 index f3667e8f1a..0000000000 --- a/backend/.sqlx/query-94a38b83d59f8c010bd96852bf57163476791448201bdd22a9e463a4116b9582.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT coalesce(flow_version_lite.value, flow_version.value) as \"value!: sqlx::types::Json>\" FROM flow \n LEFT JOIN flow_version\n ON flow_version.id = flow.versions[array_upper(flow.versions, 1)]\n LEFT JOIN flow_version_lite \n ON flow_version_lite.id = flow_version.id\n WHERE flow.path = $1 AND flow.workspace_id = $2 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "value!: sqlx::types::Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "94a38b83d59f8c010bd96852bf57163476791448201bdd22a9e463a4116b9582" -} diff --git a/backend/.sqlx/query-99a2c935acf5d6bbeb70ea1255679115b6e9042800d40899a36b3867049c5c46.json b/backend/.sqlx/query-99a2c935acf5d6bbeb70ea1255679115b6e9042800d40899a36b3867049c5c46.json index f38b293acb..f8c8963a18 100644 --- a/backend/.sqlx/query-99a2c935acf5d6bbeb70ea1255679115b6e9042800d40899a36b3867049c5c46.json +++ b/backend/.sqlx/query-99a2c935acf5d6bbeb70ea1255679115b6e9042800d40899a36b3867049c5c46.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-9c1a1d0feb79f750c7143fabb0cfa7dab8dd683cd294c27d0549bd8d78ab60a0.json b/backend/.sqlx/query-9c1a1d0feb79f750c7143fabb0cfa7dab8dd683cd294c27d0549bd8d78ab60a0.json deleted file mode 100644 index fcce977ba4..0000000000 --- a/backend/.sqlx/query-9c1a1d0feb79f750c7143fabb0cfa7dab8dd683cd294c27d0549bd8d78ab60a0.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT lock AS \"lock: String\", content AS \"code!: String\",\n language AS \"language: Option\", envs AS \"envs: Vec\", codebase AS \"codebase: String\" FROM script WHERE hash = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "lock: String", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "code!: String", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "language: Option", - "type_info": { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible" - ] - } - } - } - }, - { - "ordinal": 3, - "name": "envs: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 4, - "name": "codebase: String", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - false, - false, - true, - true - ] - }, - "hash": "9c1a1d0feb79f750c7143fabb0cfa7dab8dd683cd294c27d0549bd8d78ab60a0" -} diff --git a/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json b/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json index 981da4d667..2abc565def 100644 --- a/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json +++ b/backend/.sqlx/query-9d3556319411a27a875bf6cf0e5eda837cc63e4d8be912c0b5bfeea4a0c8db2e.json @@ -56,7 +56,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-9ee2f67042c1bed1e7d13eb7d07e78991e5d7cf01fc7993531dbedf33dac2e0b.json b/backend/.sqlx/query-9ee2f67042c1bed1e7d13eb7d07e78991e5d7cf01fc7993531dbedf33dac2e0b.json deleted file mode 100644 index 8f88e98b80..0000000000 --- a/backend/.sqlx/query-9ee2f67042c1bed1e7d13eb7d07e78991e5d7cf01fc7993531dbedf33dac2e0b.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT lock AS \"lock: String\", code AS \"code: String\", flow AS \"flow: Json>\" FROM flow_node WHERE id = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "lock: String", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "code: String", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "flow: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - true, - true - ] - }, - "hash": "9ee2f67042c1bed1e7d13eb7d07e78991e5d7cf01fc7993531dbedf33dac2e0b" -} diff --git a/backend/.sqlx/query-a21844a8a73420a1f25dac7815e525a27eda3ca6c69d690e8aa437b425c90963.json b/backend/.sqlx/query-a21844a8a73420a1f25dac7815e525a27eda3ca6c69d690e8aa437b425c90963.json deleted file mode 100644 index f43754ea67..0000000000 --- a/backend/.sqlx/query-a21844a8a73420a1f25dac7815e525a27eda3ca6c69d690e8aa437b425c90963.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n UPDATE queue SET flow_status = JSONB_SET(flow_status, ARRAY['user_states'], JSONB_SET(COALESCE(flow_status->'user_states', '{}'::jsonb), ARRAY[$1], $2))\n WHERE id = $3 AND workspace_id = $4 AND job_kind IN ('flow', 'flowpreview') RETURNING 1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "?column?", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Text", - "Jsonb", - "Uuid", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "a21844a8a73420a1f25dac7815e525a27eda3ca6c69d690e8aa437b425c90963" -} diff --git a/backend/.sqlx/query-a98b2d68f023f46ab91167d3147416df672c2aed2ba5ab70e98a9da5fa47255a.json b/backend/.sqlx/query-a98b2d68f023f46ab91167d3147416df672c2aed2ba5ab70e98a9da5fa47255a.json deleted file mode 100644 index 28bce0cd6e..0000000000 --- a/backend/.sqlx/query-a98b2d68f023f46ab91167d3147416df672c2aed2ba5ab70e98a9da5fa47255a.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_settings\n (workspace_id)\n VALUES ($1)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar" - ] - }, - "nullable": [] - }, - "hash": "a98b2d68f023f46ab91167d3147416df672c2aed2ba5ab70e98a9da5fa47255a" -} diff --git a/backend/.sqlx/query-b3a9ab85a78edf292ddb0af33f7435bbcc84f63c9079e29d84043f258eba208e.json b/backend/.sqlx/query-b3a9ab85a78edf292ddb0af33f7435bbcc84f63c9079e29d84043f258eba208e.json deleted file mode 100644 index 59bcc04054..0000000000 --- a/backend/.sqlx/query-b3a9ab85a78edf292ddb0af33f7435bbcc84f63c9079e29d84043f258eba208e.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n flow_status AS \"flow_status!: Json>\",\n coalesce(job.raw_flow, queue.raw_flow)->'modules'->(flow_status->'step')::int AS \"module: Json>\"\n FROM queue LEFT JOIN job USING(id, workspace_id) WHERE id = $1 AND workspace_id = $2 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "flow_status!: Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 1, - "name": "module: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Text" - ] - }, - "nullable": [ - true, - null - ] - }, - "hash": "b3a9ab85a78edf292ddb0af33f7435bbcc84f63c9079e29d84043f258eba208e" -} diff --git a/backend/.sqlx/query-b7f2ed32e933b65fa5455928c71f61068ad7dfee8352a76122f5af893ffe6517.json b/backend/.sqlx/query-b7f2ed32e933b65fa5455928c71f61068ad7dfee8352a76122f5af893ffe6517.json deleted file mode 100644 index e894cf3507..0000000000 --- a/backend/.sqlx/query-b7f2ed32e933b65fa5455928c71f61068ad7dfee8352a76122f5af893ffe6517.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT content AS \"content!: String\",\n lock AS \"lock: String\", language AS \"language: Option\", envs AS \"envs: Vec\", codebase AS \"codebase: String\" FROM script WHERE hash = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "content!: String", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "lock: String", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "language: Option", - "type_info": { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp" - ] - } - } - } - }, - { - "ordinal": 3, - "name": "envs: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 4, - "name": "codebase: String", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true, - false, - true, - true - ] - }, - "hash": "b7f2ed32e933b65fa5455928c71f61068ad7dfee8352a76122f5af893ffe6517" -} diff --git a/backend/.sqlx/query-bb6141ad0e93986b38ccdf4d027c486137d4fe79906e22842b711f4a9379b8c8.json b/backend/.sqlx/query-bb6141ad0e93986b38ccdf4d027c486137d4fe79906e22842b711f4a9379b8c8.json deleted file mode 100644 index da89afe0f7..0000000000 --- a/backend/.sqlx/query-bb6141ad0e93986b38ccdf4d027c486137d4fe79906e22842b711f4a9379b8c8.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n queue.job_kind AS \"job_kind: JobKind\",\n queue.script_hash AS \"script_hash: ScriptHash\",\n queue.raw_flow AS \"raw_flow: sqlx::types::Json>\",\n completed_job.parent_job AS \"parent_job: Uuid\"\n FROM queue\n JOIN completed_job ON completed_job.parent_job = queue.id\n WHERE completed_job.id = $1 AND completed_job.workspace_id = $2\n LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "job_kind: JobKind", - "type_info": { - "Custom": { - "name": "job_kind", - "kind": { - "Enum": [ - "script", - "preview", - "flow", - "dependencies", - "flowpreview", - "script_hub", - "identity", - "flowdependencies", - "http", - "graphql", - "postgresql", - "noop", - "appdependencies", - "deploymentcallback", - "singlescriptflow", - "flowscript", - "flownode", - "appscript" - ] - } - } - } - }, - { - "ordinal": 1, - "name": "script_hash: ScriptHash", - "type_info": "Int8" - }, - { - "ordinal": 2, - "name": "raw_flow: sqlx::types::Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 3, - "name": "parent_job: Uuid", - "type_info": "Uuid" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Text" - ] - }, - "nullable": [ - false, - true, - true, - true - ] - }, - "hash": "bb6141ad0e93986b38ccdf4d027c486137d4fe79906e22842b711f4a9379b8c8" -} diff --git a/backend/.sqlx/query-bc00efe12901bc7b49c7892d2d9da675e0eaf5e6cc013149740bc778987a1006.json b/backend/.sqlx/query-bc00efe12901bc7b49c7892d2d9da675e0eaf5e6cc013149740bc778987a1006.json index 6abc06cf41..67611f00dc 100644 --- a/backend/.sqlx/query-bc00efe12901bc7b49c7892d2d9da675e0eaf5e6cc013149740bc778987a1006.json +++ b/backend/.sqlx/query-bc00efe12901bc7b49c7892d2d9da675e0eaf5e6cc013149740bc778987a1006.json @@ -39,7 +39,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-bfff3d8df18db198d6ebba8a049b00147fc8bcd42f3df37ef81b9ded80974bd0.json b/backend/.sqlx/query-bfff3d8df18db198d6ebba8a049b00147fc8bcd42f3df37ef81b9ded80974bd0.json index 4843d959c1..b378d68f5b 100644 --- a/backend/.sqlx/query-bfff3d8df18db198d6ebba8a049b00147fc8bcd42f3df37ef81b9ded80974bd0.json +++ b/backend/.sqlx/query-bfff3d8df18db198d6ebba8a049b00147fc8bcd42f3df37ef81b9ded80974bd0.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-c57ed2d91de46d7de88e20b94b7afbafb622528864f2b23c8b7278bd506d967f.json b/backend/.sqlx/query-c57ed2d91de46d7de88e20b94b7afbafb622528864f2b23c8b7278bd506d967f.json deleted file mode 100644 index 0b9c0f1424..0000000000 --- a/backend/.sqlx/query-c57ed2d91de46d7de88e20b94b7afbafb622528864f2b23c8b7278bd506d967f.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT lock AS \"lock: String\", code AS \"code: String\", flow::text AS \"flow: Box\" FROM flow_node WHERE id = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "lock: String", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "code: String", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "flow: Box", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - true, - null - ] - }, - "hash": "c57ed2d91de46d7de88e20b94b7afbafb622528864f2b23c8b7278bd506d967f" -} diff --git a/backend/.sqlx/query-cd5d62d456b74237b941bc72ea8de007185263167bf1dfa2e469d319cc4da674.json b/backend/.sqlx/query-cd5d62d456b74237b941bc72ea8de007185263167bf1dfa2e469d319cc4da674.json index 912b9a53de..f550276925 100644 --- a/backend/.sqlx/query-cd5d62d456b74237b941bc72ea8de007185263167bf1dfa2e469d319cc4da674.json +++ b/backend/.sqlx/query-cd5d62d456b74237b941bc72ea8de007185263167bf1dfa2e469d319cc4da674.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-d061e7ca73987036928e17245360fd7f2969aab0c422a00bbdade6a7236aa75d.json b/backend/.sqlx/query-d061e7ca73987036928e17245360fd7f2969aab0c422a00bbdade6a7236aa75d.json deleted file mode 100644 index d6d6e77aa4..0000000000 --- a/backend/.sqlx/query-d061e7ca73987036928e17245360fd7f2969aab0c422a00bbdade6a7236aa75d.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT lock AS \"lock: String\", content AS \"code!: String\",\n language AS \"language: Option\", envs AS \"envs: Vec\", codebase AS \"codebase: String\" FROM script WHERE hash = $1 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "lock: String", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "code!: String", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "language: Option", - "type_info": { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp" - ] - } - } - } - }, - { - "ordinal": 3, - "name": "envs: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 4, - "name": "codebase: String", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - false, - false, - true, - true - ] - }, - "hash": "d061e7ca73987036928e17245360fd7f2969aab0c422a00bbdade6a7236aa75d" -} diff --git a/backend/.sqlx/query-d06efdc24706e0d7479bffc0b19a0c5976ee60125289e9f7b0b04090bce4a3a3.json b/backend/.sqlx/query-d06efdc24706e0d7479bffc0b19a0c5976ee60125289e9f7b0b04090bce4a3a3.json index 79fe0873dd..23b70ac4d2 100644 --- a/backend/.sqlx/query-d06efdc24706e0d7479bffc0b19a0c5976ee60125289e9f7b0b04090bce4a3a3.json +++ b/backend/.sqlx/query-d06efdc24706e0d7479bffc0b19a0c5976ee60125289e9f7b0b04090bce4a3a3.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-d78ecf85c1e1e95650c380c9488aa90d8d8c5c76f3971484e4c515ff60293d3b.json b/backend/.sqlx/query-d78ecf85c1e1e95650c380c9488aa90d8d8c5c76f3971484e4c515ff60293d3b.json index cdb8b928b3..1078957cf6 100644 --- a/backend/.sqlx/query-d78ecf85c1e1e95650c380c9488aa90d8d8c5c76f3971484e4c515ff60293d3b.json +++ b/backend/.sqlx/query-d78ecf85c1e1e95650c380c9488aa90d8d8c5c76f3971484e4c515ff60293d3b.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-da861c06f6448f68069ba3be9b677641c5c6b2c1e4960c74db27dbaffcbd4c40.json b/backend/.sqlx/query-da861c06f6448f68069ba3be9b677641c5c6b2c1e4960c74db27dbaffcbd4c40.json deleted file mode 100644 index 95a5b6fbf6..0000000000 --- a/backend/.sqlx/query-da861c06f6448f68069ba3be9b677641c5c6b2c1e4960c74db27dbaffcbd4c40.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT raw_code, raw_lock, raw_flow AS \"raw_flow: Json>\"\n FROM job WHERE id = $1 AND workspace_id = $2 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "raw_code", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "raw_lock", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "raw_flow: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Text" - ] - }, - "nullable": [ - true, - true, - true - ] - }, - "hash": "da861c06f6448f68069ba3be9b677641c5c6b2c1e4960c74db27dbaffcbd4c40" -} diff --git a/backend/.sqlx/query-dc44783a555d41c9df4cd303af686e43bbf89add915bfb09d94e25e8517d65ff.json b/backend/.sqlx/query-dc44783a555d41c9df4cd303af686e43bbf89add915bfb09d94e25e8517d65ff.json deleted file mode 100644 index 5f72d6aa21..0000000000 --- a/backend/.sqlx/query-dc44783a555d41c9df4cd303af686e43bbf89add915bfb09d94e25e8517d65ff.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT flow_version.value as \"value!: sqlx::types::Json>\" FROM flow \n LEFT JOIN flow_version\n ON flow_version.id = flow.versions[array_upper(flow.versions, 1)]\n WHERE flow.path = $1 AND flow.workspace_id = $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "value!: sqlx::types::Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - false - ] - }, - "hash": "dc44783a555d41c9df4cd303af686e43bbf89add915bfb09d94e25e8517d65ff" -} diff --git a/backend/.sqlx/query-deb2e4c21d4f9d0b9439780ca6ebee13450609b578c469cb437c5420ab520258.json b/backend/.sqlx/query-deb2e4c21d4f9d0b9439780ca6ebee13450609b578c469cb437c5420ab520258.json deleted file mode 100644 index 54e871eb13..0000000000 --- a/backend/.sqlx/query-deb2e4c21d4f9d0b9439780ca6ebee13450609b578c469cb437c5420ab520258.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT content FROM script WHERE hash = $1 AND workspace_id = $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "content", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Int8", - "Text" - ] - }, - "nullable": [ - false - ] - }, - "hash": "deb2e4c21d4f9d0b9439780ca6ebee13450609b578c469cb437c5420ab520258" -} diff --git a/backend/.sqlx/query-df52a71d59eb84a2b08133d25f0a8bba7f2b56625fdb7a7c0e10b51377eeb1d4.json b/backend/.sqlx/query-df52a71d59eb84a2b08133d25f0a8bba7f2b56625fdb7a7c0e10b51377eeb1d4.json deleted file mode 100644 index d1beb9d3a4..0000000000 --- a/backend/.sqlx/query-df52a71d59eb84a2b08133d25f0a8bba7f2b56625fdb7a7c0e10b51377eeb1d4.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT lock AS \"lock: String\", content AS \"code!: String\",\n language AS \"language: Option\", envs AS \"envs: Vec\", codebase AS \"codebase: String\" FROM script WHERE hash = $1 AND workspace_id = $2 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "lock: String", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "code!: String", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "language: Option", - "type_info": { - "Custom": { - "name": "script_lang", - "kind": { - "Enum": [ - "python3", - "deno", - "go", - "bash", - "postgresql", - "nativets", - "bun", - "mysql", - "bigquery", - "snowflake", - "graphql", - "powershell", - "mssql", - "php", - "bunnative", - "rust", - "ansible", - "csharp" - ] - } - } - } - }, - { - "ordinal": 3, - "name": "envs: Vec", - "type_info": "VarcharArray" - }, - { - "ordinal": 4, - "name": "codebase: String", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int8", - "Text" - ] - }, - "nullable": [ - true, - false, - false, - true, - true - ] - }, - "hash": "df52a71d59eb84a2b08133d25f0a8bba7f2b56625fdb7a7c0e10b51377eeb1d4" -} diff --git a/backend/.sqlx/query-ec7836df5f9056ec70015800b7f4feaeb1b671120f5f8c98fca8c89c6587fc35.json b/backend/.sqlx/query-ec7836df5f9056ec70015800b7f4feaeb1b671120f5f8c98fca8c89c6587fc35.json index 9fb33e41d3..81093c5f12 100644 --- a/backend/.sqlx/query-ec7836df5f9056ec70015800b7f4feaeb1b671120f5f8c98fca8c89c6587fc35.json +++ b/backend/.sqlx/query-ec7836df5f9056ec70015800b7f4feaeb1b671120f5f8c98fca8c89c6587fc35.json @@ -53,7 +53,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-f16b00bad2880f896f4452e5894fe101cd5c2fe3e4c143c0b979668143d85dd2.json b/backend/.sqlx/query-f16b00bad2880f896f4452e5894fe101cd5c2fe3e4c143c0b979668143d85dd2.json index a1ce88bd88..90413de23c 100644 --- a/backend/.sqlx/query-f16b00bad2880f896f4452e5894fe101cd5c2fe3e4c143c0b979668143d85dd2.json +++ b/backend/.sqlx/query-f16b00bad2880f896f4452e5894fe101cd5c2fe3e4c143c0b979668143d85dd2.json @@ -5,7 +5,7 @@ "columns": [ { "ordinal": 0, - "name": "?column?", + "name": "bool", "type_info": "Bool" } ], diff --git a/backend/.sqlx/query-f24303a2386575a750a48a21d1b6cdecd6e64a0415c60ad1495f100c5d85bbe1.json b/backend/.sqlx/query-f24303a2386575a750a48a21d1b6cdecd6e64a0415c60ad1495f100c5d85bbe1.json deleted file mode 100644 index 74200d658d..0000000000 --- a/backend/.sqlx/query-f24303a2386575a750a48a21d1b6cdecd6e64a0415c60ad1495f100c5d85bbe1.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT raw_flow AS \"raw_flow!: Json>\"\n FROM job WHERE id = $1 AND workspace_id = $2 LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "raw_flow!: Json>", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Uuid", - "Text" - ] - }, - "nullable": [ - true - ] - }, - "hash": "f24303a2386575a750a48a21d1b6cdecd6e64a0415c60ad1495f100c5d85bbe1" -} diff --git a/backend/.sqlx/query-f7f2598ac824e9b5719b96b1d1873ad728f7f786c7f447df6cac3e65d5a53bf1.json b/backend/.sqlx/query-f7f2598ac824e9b5719b96b1d1873ad728f7f786c7f447df6cac3e65d5a53bf1.json deleted file mode 100644 index 33bc8f1c2d..0000000000 --- a/backend/.sqlx/query-f7f2598ac824e9b5719b96b1d1873ad728f7f786c7f447df6cac3e65d5a53bf1.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT workspace.* FROM workspace, usr WHERE usr.workspace_id = workspace.id AND usr.email = $1 AND deleted = false", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "name", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "owner", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "deleted", - "type_info": "Bool" - }, - { - "ordinal": 4, - "name": "premium", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false - ] - }, - "hash": "f7f2598ac824e9b5719b96b1d1873ad728f7f786c7f447df6cac3e65d5a53bf1" -} diff --git a/backend/.sqlx/query-f9fc0084fe086ef80005bb64a8bb6b493e53583017c18e2ab44f44125c52d548.json b/backend/.sqlx/query-f9fc0084fe086ef80005bb64a8bb6b493e53583017c18e2ab44f44125c52d548.json index ce5ca3b5cd..bad609fb21 100644 --- a/backend/.sqlx/query-f9fc0084fe086ef80005bb64a8bb6b493e53583017c18e2ab44f44125c52d548.json +++ b/backend/.sqlx/query-f9fc0084fe086ef80005bb64a8bb6b493e53583017c18e2ab44f44125c52d548.json @@ -82,7 +82,8 @@ "bunnative", "rust", "ansible", - "csharp" + "csharp", + "oracledb" ] } } diff --git a/backend/.sqlx/query-fea19da213230401161cbf2ee1de521040caa6f6cc745afb7de66f4442e76cba.json b/backend/.sqlx/query-fea19da213230401161cbf2ee1de521040caa6f6cc745afb7de66f4442e76cba.json deleted file mode 100644 index d956bf8a5f..0000000000 --- a/backend/.sqlx/query-fea19da213230401161cbf2ee1de521040caa6f6cc745afb7de66f4442e76cba.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT current_setting('session.groups')", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "current_setting", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - null - ] - }, - "hash": "fea19da213230401161cbf2ee1de521040caa6f6cc745afb7de66f4442e76cba" -} diff --git a/backend/Cargo.lock b/backend/Cargo.lock index c7a8e23cf0..7c3c4c67bd 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -2103,6 +2103,16 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + [[package]] name = "darling" version = "0.14.4" @@ -2123,6 +2133,20 @@ dependencies = [ "darling_macro 0.20.10", ] +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + [[package]] name = "darling_core" version = "0.14.4" @@ -2151,6 +2175,17 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core 0.13.4", + "quote", + "syn 1.0.109", +] + [[package]] name = "darling_macro" version = "0.14.4" @@ -5644,6 +5679,15 @@ dependencies = [ "walkdir", ] +[[package]] +name = "odpic-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "920b5474a5128a9f0232df5a0ffc50aaa5b077b29b8b06ab0131985ac82793ed" +dependencies = [ + "cc", +] + [[package]] name = "once_cell" version = "1.20.2" @@ -5870,6 +5914,33 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "oracle" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db40fe6e4df881b683691ade5ef1f7b1afd52aefa115581f7b92855524d7ec0" +dependencies = [ + "cc", + "chrono", + "odpic-sys", + "once_cell", + "oracle_procmacro", + "paste", + "rustversion", +] + +[[package]] +name = "oracle_procmacro" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad247f3421d57de56a0d0408d3249d4b1048a522be2013656d92f022c3d8af27" +dependencies = [ + "darling 0.13.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ordered-float" version = "2.10.1" @@ -11211,6 +11282,7 @@ dependencies = [ "object_store", "once_cell", "opentelemetry", + "oracle", "pem 3.0.4", "postgres-native-tls", "prometheus", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 9f209282ee..2e318c4a33 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -69,6 +69,7 @@ dind = ["windmill-worker/dind"] php = ["windmill-worker/php"] rust = ["windmill-worker/rust"] mysql = ["windmill-worker/mysql"] +oracledb = ["windmill-worker/oracledb"] mssql = ["windmill-worker/mssql"] bigquery = ["windmill-worker/bigquery"] websocket = ["windmill-api/websocket"] @@ -333,3 +334,4 @@ yaml-rust = "0.4.5" tokio-tungstenite = { version = "0.24.0", features = ["native-tls"] } tree-sitter = {version = "0.23.0", features = []} tree-sitter-c-sharp = "0.23.0" +oracle = { version = "0.6.3", features = ["chrono"] } diff --git a/backend/migrations/20250110123428_oracledb_support.down.sql b/backend/migrations/20250110123428_oracledb_support.down.sql new file mode 100644 index 0000000000..d2f607c5b8 --- /dev/null +++ b/backend/migrations/20250110123428_oracledb_support.down.sql @@ -0,0 +1 @@ +-- Add down migration script here diff --git a/backend/migrations/20250110123428_oracledb_support.up.sql b/backend/migrations/20250110123428_oracledb_support.up.sql new file mode 100644 index 0000000000..3e9da56859 --- /dev/null +++ b/backend/migrations/20250110123428_oracledb_support.up.sql @@ -0,0 +1,3 @@ +-- Add up migration script here +ALTER TYPE SCRIPT_LANG ADD VALUE IF NOT EXISTS 'oracledb'; +UPDATE config set config = jsonb_set(config, '{worker_tags}', config->'worker_tags' || '["oracledb"]'::jsonb) where name = 'worker__native' and config @> '{"worker_tags": ["deno", "python3", "go", "bash", "powershell", "dependency", "flow", "hub", "other", "bun", "php", "rust", "ansible", "csharp"]}'::jsonb AND NOT config->'worker_tags' @> '"oracledb"'::jsonb; diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 0000000000..dfb18f1156 --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "backend", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/backend/parsers/windmill-parser-sql/src/lib.rs b/backend/parsers/windmill-parser-sql/src/lib.rs index 1188542d49..f5ddb73151 100644 --- a/backend/parsers/windmill-parser-sql/src/lib.rs +++ b/backend/parsers/windmill-parser-sql/src/lib.rs @@ -32,6 +32,22 @@ pub fn parse_mysql_sig(code: &str) -> anyhow::Result { } } +pub fn parse_oracledb_sig(code: &str) -> anyhow::Result { + let parsed = parse_oracledb_file(&code)?; + if let Some(x) = parsed { + let args = x; + Ok(MainArgSignature { + star_args: false, + star_kwargs: false, + args, + no_main_func: None, + has_preprocessor: None, + }) + } else { + Err(anyhow!("Error parsing sql".to_string())) + } +} + pub fn parse_pgsql_sig(code: &str) -> anyhow::Result { let parsed = parse_pg_file(&code)?; if let Some(x) = parsed { @@ -157,6 +173,61 @@ fn parsed_default(parsed_typ: &Typ, default: String) -> Option Some(json!(default)), } } + +fn parse_oracledb_file(code: &str) -> anyhow::Result>> { + let mut args: Vec = vec![]; + + let mut using_named_args = false; + for cap in RE_ARG_MYSQL_NAMED.captures_iter(code) { + using_named_args = true; + let name = cap.get(1).map(|x| x.as_str().to_string()).unwrap(); + let typ = cap + .get(2) + .map(|x| x.as_str().to_string().to_lowercase()) + .unwrap(); + let default = cap.get(3).map(|x| x.as_str().to_string()); + let has_default = default.is_some(); + let parsed_typ = parse_oracledb_typ(typ.as_str()); + + let parsed_default = default.and_then(|x| parsed_default(&parsed_typ, x)); + args.push(Arg { + name, + typ: parsed_typ, + default: parsed_default, + otyp: Some(typ), + has_default, + oidx: None, + }); + } + + if !using_named_args { + // backwards compatibility + for cap in RE_ARG_MYSQL.captures_iter(code) { + let name = cap.get(1).map(|x| x.as_str().to_string()).unwrap(); + let typ = cap + .get(2) + .map(|x| x.as_str().to_string().to_lowercase()) + .unwrap(); + let default = cap.get(3).map(|x| x.as_str().to_string()); + let has_default = default.is_some(); + let parsed_typ = parse_oracledb_typ(typ.as_str()); + + let parsed_default = default.and_then(|x| parsed_default(&parsed_typ, x)); + + args.push(Arg { + name, + typ: parsed_typ, + default: parsed_default, + otyp: Some(typ), + has_default, + oidx: None, + }); + } + } + + Ok(Some(args)) +} + fn parse_mysql_file(code: &str) -> anyhow::Result>> { let mut args: Vec = vec![]; @@ -486,6 +557,18 @@ pub fn parse_mysql_typ(typ: &str) -> Typ { } } +pub fn parse_oracledb_typ(typ: &str) -> Typ { + match typ { + "varchar" | "nvarchar" | "varchar2" | "char" | "nchar" | "nvarchar2" | "clob" | "blob" + | "nclob" => Typ::Str(None), + "integer" | "int" | "long" | "rowid" | "urowid" => Typ::Int, + "bool" => Typ::Bool, + "number" | "float" | "binary_float" | "binary_double" => Typ::Float, + "date" | "datetime" | "timestamp" | "time" => Typ::Datetime, + _ => Typ::Str(None), + } +} + pub fn parse_pg_typ(typ: &str) -> Typ { if typ.ends_with("[]") { let base_typ = parse_pg_typ(typ.strip_suffix("[]").unwrap()); diff --git a/backend/parsers/windmill-parser-wasm/src/lib.rs b/backend/parsers/windmill-parser-wasm/src/lib.rs index 50ebf232ac..e3de739f96 100644 --- a/backend/parsers/windmill-parser-wasm/src/lib.rs +++ b/backend/parsers/windmill-parser-wasm/src/lib.rs @@ -88,6 +88,12 @@ pub fn parse_mysql(code: &str) -> String { wrap_sig(windmill_parser_sql::parse_mysql_sig(code)) } +#[cfg(feature = "sql-parser")] +#[wasm_bindgen] +pub fn parse_oracledb(code: &str) -> String { + wrap_sig(windmill_parser_sql::parse_oracledb_sig(code)) +} + #[cfg(feature = "sql-parser")] #[wasm_bindgen] pub fn parse_bigquery(code: &str) -> String { diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 7855dac778..b33a425804 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -10992,6 +10992,7 @@ components: bigquery, snowflake, mssql, + oracledb, graphql, nativets, bun, @@ -11097,6 +11098,7 @@ components: bigquery, snowflake, mssql, + oracledb, graphql, nativets, bun, @@ -11324,6 +11326,7 @@ components: bigquery, snowflake, mssql, + oracledb, graphql, nativets, bun, @@ -11447,6 +11450,7 @@ components: bigquery, snowflake, mssql, + oracledb, graphql, nativets, bun, @@ -12003,6 +12007,7 @@ components: bigquery, snowflake, mssql, + oracledb, graphql, nativets, bun, @@ -13747,6 +13752,7 @@ components: bigquery, snowflake, mssql, + oracledb, graphql, nativets, bun, diff --git a/backend/windmill-api/src/workspaces_export.rs b/backend/windmill-api/src/workspaces_export.rs index 7ab9481569..159a9962a0 100644 --- a/backend/windmill-api/src/workspaces_export.rs +++ b/backend/windmill-api/src/workspaces_export.rs @@ -354,6 +354,7 @@ pub(crate) async fn tarball_workspace( ScriptLang::Rust => "rs", ScriptLang::Ansible => "playbook.yml", ScriptLang::CSharp => "cs", + ScriptLang::OracleDB => "oracle.sql", }; archive .write_to_archive(&script.content, &format!("{}.{}", script.path, ext)) diff --git a/backend/windmill-common/src/scripts.rs b/backend/windmill-common/src/scripts.rs index 2d7cd0a5e7..11c4aa01d4 100644 --- a/backend/windmill-common/src/scripts.rs +++ b/backend/windmill-common/src/scripts.rs @@ -42,6 +42,7 @@ pub enum ScriptLang { Snowflake, Graphql, Mssql, + OracleDB, Php, Rust, Ansible, @@ -65,6 +66,7 @@ impl ScriptLang { ScriptLang::Snowflake => "snowflake", ScriptLang::Mssql => "mssql", ScriptLang::Graphql => "graphql", + ScriptLang::OracleDB => "oracledb", ScriptLang::Php => "php", ScriptLang::Rust => "rust", ScriptLang::Ansible => "ansible", diff --git a/backend/windmill-worker/Cargo.toml b/backend/windmill-worker/Cargo.toml index 890d3f3a70..7bec644550 100644 --- a/backend/windmill-worker/Cargo.toml +++ b/backend/windmill-worker/Cargo.toml @@ -25,6 +25,7 @@ otel = ["windmill-common/otel", "dep:opentelemetry"] dind = ["dep:bollard"] php = ["dep:windmill-parser-php"] mysql = ["dep:mysql_async"] +oracledb = ["dep:oracle"] python = ["dep:windmill-parser-py", "dep:windmill-parser-py-imports"] csharp = ["dep:windmill-parser-csharp"] rust = ["dep:windmill-parser-rust"] @@ -104,6 +105,7 @@ backon.workspace = true opentelemetry = { workspace = true, optional = true } bollard = { workspace = true, optional = true } +oracle = { workspace = true, optional = true } [build-dependencies] deno_fetch = { workspace = true, optional = true } diff --git a/backend/windmill-worker/src/lib.rs b/backend/windmill-worker/src/lib.rs index 4a8766099d..d887f14d81 100644 --- a/backend/windmill-worker/src/lib.rs +++ b/backend/windmill-worker/src/lib.rs @@ -36,6 +36,8 @@ mod rust_executor; mod worker; mod worker_flow; mod worker_lockfiles; +#[cfg(feature = "oracledb")] +mod oracledb_executor; pub use worker::*; pub use result_processor::handle_job_error; diff --git a/backend/windmill-worker/src/oracledb_executor.rs b/backend/windmill-worker/src/oracledb_executor.rs new file mode 100644 index 0000000000..fc5686568e --- /dev/null +++ b/backend/windmill-worker/src/oracledb_executor.rs @@ -0,0 +1,418 @@ +use anyhow::anyhow; +use chrono::Utc; +use std::{collections::HashMap, str::FromStr, sync::Arc}; +use windmill_parser::Arg; + +use futures::{future::BoxFuture, FutureExt}; +use itertools::Itertools; +use oracle::sql_type::{InnerValue, OracleType, ToSql}; +use serde::{Deserialize, Serialize}; +use serde_json::{json, value::RawValue, Value}; +use sqlx::types::Json; +use windmill_common::{ + error::{to_anyhow, Error}, + jobs::QueuedJob, + worker::to_raw_value, +}; +use windmill_parser_sql::{ + parse_db_resource, parse_oracledb_sig, parse_sql_blocks, parse_sql_statement_named_params, +}; +use windmill_queue::CanceledBy; + +use crate::{ + common::{check_executor_binary_exists, build_args_map, OccupancyMetrics}, + handle_child::run_future_with_polling_update_job_poller, + AuthedClientBackgroundTask, +}; + +#[derive(Deserialize)] +struct OracleDatabase { + user: String, + password: String, + database: String, +} + +lazy_static::lazy_static! { + static ref ORACLE_LIB_DIR: String = std::env::var("ORACLE_LIB_DIR").unwrap_or_else(|_| "/opt/oracle/23/lib".to_string()); +} + +pub fn do_oracledb_inner<'a>( + query: &str, + params: Vec<(String, Box)>, + conn: Arc>, + column_order: Option<&'a mut Option>>, + skip_collect: bool, +) -> windmill_common::error::Result>>> { + let qw = query.trim_end_matches(';').to_string(); + + let result_f = async move { + let param_names = parse_sql_statement_named_params(&qw, ':') + .into_iter() + .map(|x| x.into_bytes()) + .collect_vec(); + + if skip_collect { + tokio::task::spawn_blocking(move || { + let c = conn.lock()?; + + let params2: Vec<(&str, &dyn ToSql)> = params + .iter() + .filter(|(k, _)| param_names.contains(&k.clone().into_bytes())) + .map(|(key, val)| (key.as_str(), &**val as &dyn ToSql)) + .collect(); + + let mut stmt = c.statement(&qw).build()?; + + match stmt.statement_type() { + oracle::StatementType::Select => { + stmt.query_named(¶ms2)?; + } + _ => { + stmt.execute_named(¶ms2)?; + c.commit()?; + } + } + oracle::Result::Ok(()) + }) + .await + .map_err(to_anyhow)? + .map_err(to_anyhow)?; + + Ok(to_raw_value(&Value::Array(vec![]))) + } else { + let rows = tokio::task::spawn_blocking(move || { + let params2: Vec<(&str, &dyn ToSql)> = params + .iter() + .filter(|(k, _)| param_names.contains(&k.clone().into_bytes())) + .map(|(key, val)| (key.as_str(), &**val as &dyn ToSql)) + .collect(); + + let c = conn.lock()?; + let mut stmt = c.statement(&qw).build()?; + + let rows = match stmt.statement_type() { + oracle::StatementType::Select => { + let result_rows = stmt.query_named(¶ms2)?; + let rows: Vec = + result_rows.into_iter().filter_map(Result::ok).collect_vec(); + rows + } + _ => { + stmt.execute_named(¶ms2)?; + c.commit()?; + vec![] + } + }; + + oracle::Result::Ok(rows) + }) + .await + .map_err(to_anyhow)? + .map_err(to_anyhow)?; + + if let Some(column_order) = column_order { + *column_order = Some( + rows.first() + .map(|x| { + x.column_info() + .iter() + .map(|x| x.name().to_string()) + .collect::>() + }) + .unwrap_or_default(), + ); + } + + Ok(to_raw_value( + &rows + .into_iter() + .map(|x| convert_row_to_value(x)) + .collect::>(), + )) + } + }; + + Ok(result_f.boxed()) +} + +fn convert_row_to_value(row: oracle::Row) -> serde_json::Value { + let mut map = serde_json::Map::new(); + + for (key, value) in row.column_info().iter().zip(row.sql_values()) { + map.insert( + key.name().to_string(), + convert_oracledb_value_to_json(value, key.oracle_type()), + ); + } + serde_json::Value::Object(map) +} + +fn conversion_error(r: Result) -> serde_json::Value { + match r { + Ok(v) => json!(v), + Err(e) => json!(format!("Error converting value: {:?}", e)), + } +} + +fn convert_oracledb_value_to_json(v: &oracle::SqlValue, c: &OracleType) -> serde_json::Value { + match v.as_inner_value() { + Err(_) => serde_json::Value::Null, + Ok(iv) => match iv { + InnerValue::Int64(n) => json!(n), + InnerValue::UInt64(n) => json!(n), + InnerValue::Float(n) => json!(n), + InnerValue::Double(n) => json!(n), + InnerValue::Char(n) => json!(String::from_utf8_lossy(n)), + InnerValue::Number(n) => json!(n), + InnerValue::Boolean(n) => json!(n), + InnerValue::Timestamp(_) => conversion_error(v.get::()), + InnerValue::IntervalDS(_) => conversion_error(v.get::()), + InnerValue::IntervalYM(_) => conversion_error(v.get::()), + InnerValue::Clob(_) => json!("Unsupported type Clob"), + InnerValue::Blob(_) => json!("Unsupported type Blob"), + InnerValue::Rowid(_) => json!("Unsupported type Rowid"), + InnerValue::Object(_) => json!("Unsuppported type Object"), + InnerValue::Stmt(_) => json!("Unsupported type Stmt"), + InnerValue::Raw(b) => { + match c { + OracleType::Varchar2(_) + | OracleType::NVarchar2(_) + | OracleType::Char(_) + | OracleType::NChar(_) + | OracleType::Json + | OracleType::Xml => { + let s = String::from_utf8_lossy(b); + json!(s) + } + + // OracleType::Rowid => todo!(), + // OracleType::Raw(_) => todo!(), + // + // OracleType::BinaryFloat => todo!(), + // OracleType::BinaryDouble => todo!(), + // OracleType::Number(_, _) => todo!(), + // OracleType::Float(_) => todo!(), + // OracleType::Int64 => todo!(), + // OracleType::UInt64 => todo!(), + // OracleType::Long => todo!(), + // OracleType::LongRaw => todo!(), + OracleType::Date + | OracleType::Timestamp(_) + | OracleType::TimestampTZ(_) + | OracleType::TimestampLTZ(_) + | OracleType::IntervalDS(_, _) + | OracleType::IntervalYM(_) => conversion_error(v.get::()), + + // OracleType::CLOB => todo!(), + // OracleType::NCLOB => todo!(), + // OracleType::BLOB => todo!(), + // OracleType::BFILE => todo!(), + // OracleType::RefCursor => todo!(), + // OracleType::Boolean => todo!(), + // OracleType::Object(_) => todo!(), + _ => json!(format!("Unsupported type: {c:?}")), + } + } + _ => json!(format!("Unsupported type: {c:?}")), + }, + } +} + +fn get_statement_values( + sig: Vec, + job_args: Option<&Json>>>, +) -> (Vec<(String, Box)>, Vec) { + let mut statement_values = vec![]; + let mut errors = vec![]; + + for arg in &sig { + let arg_t = arg.otyp.clone().unwrap_or_else(|| "text".to_string()); + let arg_n = arg.name.clone(); + let oracle_v: Box = match job_args + .and_then(|x| { + x.get(arg.name.as_str()) + .map(|x| serde_json::from_str::(x.get()).ok()) + }) + .flatten() + .unwrap_or_else(|| json!(null)) + { + // Value::Null => todo!(), + Value::Bool(b) => Box::new(b), + Value::String(s) + if arg_t == "timestamp" + || arg_t == "datetime" + || arg_t == "date" + || arg_t == "time" => + { + if let Ok(d) = chrono::DateTime::::from_str(s.as_str()) { + Box::new(d) + } else { + Box::new(s) + } + } + Value::String(s) => Box::new(s), + Value::Number(n) + if n.is_i64() + && (arg_t == "int" + || arg_t == "integer" + || arg_t == "smallint" + || arg_t == "bigint") => + { + Box::new(n.as_i64().unwrap()) + } + Value::Number(n) if n.is_f64() && arg_t == "float" => { + Box::new(n.as_f64().unwrap() as f32) + } + Value::Number(n) if n.is_i64() && arg_t == "float" => { + Box::new(n.as_i64().unwrap() as f32) + } + Value::Number(n) if n.is_u64() && arg_t == "uint" => Box::new(n.as_u64().unwrap()), + Value::Number(n) + if n.is_f64() && (arg_t == "real" || arg_t == "dec" || arg_t == "fixed") => + { + Box::new(n.as_f64().unwrap()) + } + Value::Number(n) + if n.is_i64() && (arg_t == "real" || arg_t == "dec" || arg_t == "fixed") => + { + Box::new(n.as_i64().unwrap() as f64) + } + value @ _ => { + errors.push(format!( + "Unsupported type in query: {value:?} and signature {arg_t:?} for {arg_n}" + )); + continue; + } + }; + + statement_values.push((arg_n, oracle_v)); + } + + (statement_values, errors) +} + +pub async fn do_oracledb( + job: &QueuedJob, + client: &AuthedClientBackgroundTask, + query: &str, + db: &sqlx::Pool, + mem_peak: &mut i32, + canceled_by: &mut Option, + worker_name: &str, + column_order: &mut Option>, + occupancy_metrics: &mut OccupancyMetrics, +) -> windmill_common::error::Result> { + check_executor_binary_exists("the Oracle client lib", ORACLE_LIB_DIR.as_str(), "Oracle Database")?; + + let args = build_args_map(job, client, db).await?.map(Json); + let job_args = if args.is_some() { + args.as_ref() + } else { + job.args.as_ref() + }; + + let inline_db_res_path = parse_db_resource(&query); + + let db_arg = if let Some(inline_db_res_path) = inline_db_res_path { + let val = client + .get_authed() + .await + .get_resource_value_interpolated::( + &inline_db_res_path, + Some(job.id.to_string()), + ) + .await?; + + let as_raw = serde_json::from_value(val).map_err(|e| { + Error::InternalErr(format!("Error while parsing inline resource: {e:#}")) + })?; + + Some(as_raw) + } else { + job_args.and_then(|x| x.get("database").cloned()) + }; + + let database = if let Some(db) = db_arg { + serde_json::from_str::(db.get()) + .map_err(|e| Error::ExecutionErr(e.to_string()))? + } else { + return Err(Error::BadRequest("Missing database argument".to_string())); + }; + + let annotations = windmill_common::worker::SqlAnnotations::parse(query); + + let sig = parse_oracledb_sig(query) + .map_err(|x| Error::ExecutionErr(x.to_string()))? + .args; + + let (statement_values, errors) = get_statement_values(sig.clone(), job_args); + + if !errors.is_empty() { + return Err(Error::ExecutionErr(errors.join("\n"))); + } + + if !oracle::InitParams::is_initialized() { + let _ = oracle::InitParams::new() + .oracle_client_lib_dir(ORACLE_LIB_DIR.as_str()) + .map_err(|e| anyhow!("Failed to initialize oracle client: {e}"))? + .init(); + } + + let conn = tokio::task::spawn_blocking(|| { + oracle::Connection::connect(database.user, database.password, database.database) + .map_err(|e| Error::ExecutionErr(e.to_string())) + }) + .await + .map_err(to_anyhow)??; + + let conn_a = Arc::new(std::sync::Mutex::new(conn)); + + let queries = parse_sql_blocks(query); + + let result_f = if queries.len() > 1 { + let f = async { + let mut res: Vec> = vec![]; + for (i, q) in queries.iter().enumerate() { + let (vals, _) = get_statement_values(sig.clone(), job_args); + let r = do_oracledb_inner( + q, + vals, + conn_a.clone(), + None, + annotations.return_last_result && i < queries.len() - 1, + )? + .await?; + res.push(r); + } + + if annotations.return_last_result && res.len() > 0 { + Ok(res.pop().unwrap()) + } else { + Ok(to_raw_value(&res)) + } + }; + + f.boxed() + } else { + do_oracledb_inner(query, statement_values, conn_a, Some(column_order), false)? + }; + + let result = run_future_with_polling_update_job_poller( + job.id, + job.timeout, + db, + mem_peak, + canceled_by, + result_f, + worker_name, + &job.workspace_id, + &mut Some(occupancy_metrics), + Box::pin(futures::stream::once(async { 0 })), + ) + .await?; + + let raw_result = windmill_common::worker::to_raw_value(&json!(result)); + *mem_peak = (raw_result.get().len() / 1000) as i32; + + return Ok(raw_result); +} diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index 88e556a2b7..0a0599047f 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -90,26 +90,12 @@ use tokio::{ use rand::Rng; use crate::{ - bash_executor::{handle_bash_job, handle_powershell_job}, - bun_executor::handle_bun_job, - common::{ + bash_executor::{handle_bash_job, handle_powershell_job}, bun_executor::handle_bun_job, common::{ build_args_map, cached_result_path, get_cached_resource_value_if_valid, get_reserved_variables, update_worker_ping_for_failed_init_script, OccupancyMetrics, - }, - csharp_executor::handle_csharp_job, - deno_executor::handle_deno_job, - go_executor::handle_go_job, - graphql_executor::do_graphql, - handle_child::SLOW_LOGS, - handle_job_error, - job_logger::NO_LOGS_AT_ALL, - js_eval::{eval_fetch_timeout, transpile_ts}, - pg_executor::do_postgresql, - result_processor::{process_result, start_background_processor}, - worker_flow::{handle_flow, update_flow_status_in_progress}, - worker_lockfiles::{ + }, csharp_executor::handle_csharp_job, deno_executor::handle_deno_job, go_executor::handle_go_job, graphql_executor::do_graphql, handle_child::SLOW_LOGS, handle_job_error, job_logger::NO_LOGS_AT_ALL, js_eval::{eval_fetch_timeout, transpile_ts}, pg_executor::do_postgresql, result_processor::{process_result, start_background_processor}, worker_flow::{handle_flow, update_flow_status_in_progress}, worker_lockfiles::{ handle_app_dependency_job, handle_dependency_job, handle_flow_dependency_job, - }, + } }; #[cfg(feature = "rust")] @@ -127,6 +113,9 @@ use crate::ansible_executor::handle_ansible_job; #[cfg(feature = "mysql")] use crate::mysql_executor::do_mysql; +#[cfg(feature = "oracledb")] +use crate::oracledb_executor::do_oracledb; + use backon::ConstantBuilder; use backon::{BackoffBuilder, Retryable}; @@ -2480,6 +2469,37 @@ async fn handle_code_execution_job( ) .await; } + } else if language == Some(ScriptLang::OracleDB) { + #[cfg(not(feature = "enterprise"))] + { + return Err(Error::ExecutionErr( + "Oracle DB is only available with an enterprise license".to_string(), + )); + } + + #[allow(unreachable_code)] + #[cfg(not(feature = "oracledb"))] + { + return Err(Error::InternalErr( + "Oracle DB requires the oracledb feature to be enabled".to_string(), + )); + } + + #[cfg(all(feature = "enterprise", feature = "oracledb"))] + { + return do_oracledb( + job, + &client, + &code, + db, + mem_peak, + canceled_by, + worker_name, + column_order, + occupancy_metrics, + ) + .await; + } } else if language == Some(ScriptLang::Graphql) { return do_graphql( job, diff --git a/backend/windmill-worker/src/worker_lockfiles.rs b/backend/windmill-worker/src/worker_lockfiles.rs index 213eb2dca5..06b7e4f0d2 100644 --- a/backend/windmill-worker/src/worker_lockfiles.rs +++ b/backend/windmill-worker/src/worker_lockfiles.rs @@ -1946,6 +1946,7 @@ async fn capture_dependency_job( ScriptLang::Snowflake => Ok("".to_owned()), ScriptLang::Mssql => Ok("".to_owned()), ScriptLang::Graphql => Ok("".to_owned()), + ScriptLang::OracleDB => Ok("".to_owned()), ScriptLang::Bash => Ok("".to_owned()), ScriptLang::Powershell => Ok("".to_owned()), ScriptLang::Nativets => Ok("".to_owned()), diff --git a/docker/DockerfileFullEe b/docker/DockerfileFullEe index 5f7870cc82..6b4873bb02 100644 --- a/docker/DockerfileFullEe +++ b/docker/DockerfileFullEe @@ -8,3 +8,6 @@ RUN pip3 install ansible COPY --from=bitnami/dotnet-sdk:9.0.101-debian-12-r0 /opt/bitnami/dotnet-sdk /opt/dotnet-sdk RUN ln -s /opt/dotnet-sdk/bin/dotnet /usr/bin/dotnet ENV DOTNET_ROOT="/opt/dotnet-sdk/bin" + +# Oracle DB Client +COPY --from=ghcr.io/oracle/oraclelinux9-instantclient:23 /usr/lib/oracle/23/client64/lib /opt/oracle/23/lib diff --git a/docker/DockerfileNsjail b/docker/DockerfileNsjail index a94d4e8d49..7802ad3f90 100644 --- a/docker/DockerfileNsjail +++ b/docker/DockerfileNsjail @@ -34,4 +34,7 @@ COPY --from=bitnami/dotnet-sdk:9.0.101-debian-12-r0 /opt/bitnami/dotnet-sdk /opt RUN ln -s /opt/dotnet-sdk/bin/dotnet /usr/bin/dotnet ENV DOTNET_ROOT="/opt/dotnet-sdk/bin" +# Oracle DB Client +COPY --from=ghcr.io/oracle/oraclelinux9-instantclient:23 /usr/lib/oracle/23/client64/lib /opt/oracle/23/lib + COPY --from=nsjail /nsjail/nsjail /bin/nsjail diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2b26b0864d..f486817e87 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -75,7 +75,7 @@ "windmill-parser-wasm-go": "^1.429.0", "windmill-parser-wasm-php": "^1.429.0", "windmill-parser-wasm-py": "^1.429.0", - "windmill-parser-wasm-regex": "^1.435.2", + "windmill-parser-wasm-regex": "^1.439.0", "windmill-parser-wasm-rust": "^1.429.0", "windmill-parser-wasm-ts": "^1.429.0", "windmill-parser-wasm-yaml": "^1.429.0", @@ -13991,9 +13991,9 @@ "integrity": "sha512-cqc+tblQVHVrc8wNA4esVYD1Dv59XQJ4mHXFFPa8Lx5UjXv7FO/0VQxyQuRyXaP/V6J6DDy0oeN107eFNLxrBg==" }, "node_modules/windmill-parser-wasm-regex": { - "version": "1.435.2", - "resolved": "https://registry.npmjs.org/windmill-parser-wasm-regex/-/windmill-parser-wasm-regex-1.435.2.tgz", - "integrity": "sha512-kQShKPNjXok8jV7b7llfvKhypHfqePwiKgTHm8MlzBt4BZC87xrQ7TH0eS9h7OSK9Q98H9fIiUr2AbN8zTCraA==" + "version": "1.439.0", + "resolved": "https://registry.npmjs.org/windmill-parser-wasm-regex/-/windmill-parser-wasm-regex-1.439.0.tgz", + "integrity": "sha512-v7vcEOWurGbqvoTdtQ8wauyUYeuQExRCmr7phPtwUwD+1cNbqDrS11kM8p2Na3DXjL9RqGAGjd6uRjNSccZjjQ==" }, "node_modules/windmill-parser-wasm-rust": { "version": "1.429.0", diff --git a/frontend/package.json b/frontend/package.json index 2bf6887471..10f4bbca5d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -150,7 +150,7 @@ "windmill-parser-wasm-go": "^1.429.0", "windmill-parser-wasm-php": "^1.429.0", "windmill-parser-wasm-py": "^1.429.0", - "windmill-parser-wasm-regex": "^1.435.2", + "windmill-parser-wasm-regex": "^1.439.0", "windmill-parser-wasm-rust": "^1.429.0", "windmill-parser-wasm-ts": "^1.429.0", "windmill-parser-wasm-yaml": "^1.429.0", diff --git a/frontend/src/lib/components/AppConnectInner.svelte b/frontend/src/lib/components/AppConnectInner.svelte index bd10721792..6a756071dd 100644 --- a/frontend/src/lib/components/AppConnectInner.svelte +++ b/frontend/src/lib/components/AppConnectInner.svelte @@ -41,7 +41,8 @@ 'bigquery', 'snowflake', 'mssql', - 'graphql' + 'graphql', + 'oracledb' ] let filter = '' diff --git a/frontend/src/lib/components/Editor.svelte b/frontend/src/lib/components/Editor.svelte index 1f3dcb83b2..96d95feb12 100644 --- a/frontend/src/lib/components/Editor.svelte +++ b/frontend/src/lib/components/Editor.svelte @@ -163,6 +163,7 @@ BIGQUERY_TYPES, MSSQL_TYPES, MYSQL_TYPES, + ORACLEDB_TYPES, POSTGRES_TYPES, SNOWFLAKE_TYPES } from '$lib/consts' @@ -462,6 +463,8 @@ ? BIGQUERY_TYPES : scriptLang === 'mssql' ? MSSQL_TYPES + : scriptLang === 'oracledb' + ? ORACLEDB_TYPES : [] ).map((t) => ({ label: t, diff --git a/frontend/src/lib/components/HighlightCode.svelte b/frontend/src/lib/components/HighlightCode.svelte index 80857ef0b0..40c296a44e 100644 --- a/frontend/src/lib/components/HighlightCode.svelte +++ b/frontend/src/lib/components/HighlightCode.svelte @@ -50,6 +50,8 @@ return sql case 'bigquery': return sql + case 'oracledb': + return sql case 'powershell': return powershell case 'php': diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 38c537b407..6ad2a818c5 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -158,7 +158,7 @@ showCaptureHint: showCaptureHint }) - const enterpriseLangs = ['bigquery', 'snowflake', 'mssql'] + const enterpriseLangs = ['bigquery', 'snowflake', 'mssql', 'oracledb'] export function setCode(code: string): void { editor?.setCode(code) diff --git a/frontend/src/lib/components/TestConnection.svelte b/frontend/src/lib/components/TestConnection.svelte index 3569fc070f..321b39ceac 100644 --- a/frontend/src/lib/components/TestConnection.svelte +++ b/frontend/src/lib/components/TestConnection.svelte @@ -50,6 +50,11 @@ lang: 'mssql', argName: 'database' }, + oracledb: { + code: `SELECT 1`, + lang: 'oracledb', + argName: 'database' + }, s3: { code: ` import * as wmill from "windmill-client" diff --git a/frontend/src/lib/components/WorkerGroup.svelte b/frontend/src/lib/components/WorkerGroup.svelte index e09e5793a4..7c02060692 100644 --- a/frontend/src/lib/components/WorkerGroup.svelte +++ b/frontend/src/lib/components/WorkerGroup.svelte @@ -131,7 +131,8 @@ 'graphql', 'snowflake', 'mssql', - 'bigquery' + 'bigquery', + 'oracledb' ] const aws_env_vars_preset = [ diff --git a/frontend/src/lib/components/apps/editor/component/default-codes.ts b/frontend/src/lib/components/apps/editor/component/default-codes.ts index 1758d6dfd4..51b3353724 100644 --- a/frontend/src/lib/components/apps/editor/component/default-codes.ts +++ b/frontend/src/lib/components/apps/editor/component/default-codes.ts @@ -23,7 +23,8 @@ export const DEFAULT_CODES: Partial< | 'postgresql' | 'snowflake' | 'mssql' - | 'bigquery', + | 'bigquery' + | 'oracledb', string > > diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte index 3137b6d229..0f6355d1df 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte @@ -73,7 +73,7 @@ {:else if fieldType === 'tab-select'} - {:else if fieldType === 'resource' && subFieldType && ['mysql', 'postgres', 'ms_sql_server', 'snowflake', 'snowflake_oauth', 'bigquery'].includes(subFieldType)} + {:else if fieldType === 'resource' && subFieldType && ['mysql', 'postgres', 'ms_sql_server', 'snowflake', 'snowflake_oauth', 'bigquery', 'oracledb'].includes(subFieldType)} { diff --git a/frontend/src/lib/components/apps/inputType.ts b/frontend/src/lib/components/apps/inputType.ts index e31a33c78f..237d7bbd61 100644 --- a/frontend/src/lib/components/apps/inputType.ts +++ b/frontend/src/lib/components/apps/inputType.ts @@ -40,6 +40,7 @@ export type InputType = | 'snowflake' | 'snowflake_oauth' | 'bigquery' + | 'oracledb' | 'app-path' // Connection to an output of another component @@ -227,6 +228,7 @@ export type AppInput = | AppInputSpec<'resource', string, 'snowflake'> | AppInputSpec<'resource', string, 'snowflake_oauth'> | AppInputSpec<'resource', string, 'bigquery'> + | AppInputSpec<'resource', string, 'oracledb'> | AppInputSpec<'array', object[], 'number-tuple'> | AppInputSpec<'app-path', string> diff --git a/frontend/src/lib/components/common/languageIcons/LanguageIcon.svelte b/frontend/src/lib/components/common/languageIcons/LanguageIcon.svelte index 565865d821..f3855adce0 100644 --- a/frontend/src/lib/components/common/languageIcons/LanguageIcon.svelte +++ b/frontend/src/lib/components/common/languageIcons/LanguageIcon.svelte @@ -9,6 +9,7 @@ import RestIcon from '$lib/components/icons/RestIcon.svelte' import PowershellIcon from '$lib/components/icons/PowershellIcon.svelte' import BigQueryIcon from '$lib/components/icons/BigQueryIcon.svelte' + import OracleDBIcon from '$lib/components/icons/OracleDBIcon.svelte' import SnowflakeIcon from '$lib/components/icons/SnowflakeIcon.svelte' import GraphqlIcon from '$lib/components/icons/GraphqlIcon.svelte' import MSSqlServerIcon from '$lib/components/icons/MSSqlServerIcon.svelte' @@ -45,6 +46,7 @@ graphql: 'GraphQL', postgresql: 'Postgresql', bigquery: 'BigQuery', + oracledb: 'Oracle Database', snowflake: 'Snowflake', mysql: 'MySQL', mssql: 'MS SQL Server', @@ -69,6 +71,7 @@ pgsql: PostgresIcon, mysql: MySQLIcon, bigquery: BigQueryIcon, + oracledb: OracleDBIcon, snowflake: SnowflakeIcon, mssql: MSSqlServerIcon, javascript: JavaScript, diff --git a/frontend/src/lib/components/copilot/ScriptGen.svelte b/frontend/src/lib/components/copilot/ScriptGen.svelte index ae711bd380..16365dd715 100644 --- a/frontend/src/lib/components/copilot/ScriptGen.svelte +++ b/frontend/src/lib/components/copilot/ScriptGen.svelte @@ -471,7 +471,7 @@ {/if} - {#if ['postgresql', 'mysql', 'snowflake', 'bigquery', 'mssql', 'graphql'].includes(lang ?? '') && dbSchema?.lang === lang} + {#if ['postgresql', 'mysql', 'snowflake', 'bigquery', 'mssql', 'graphql, oracledb'].includes(lang ?? '') && dbSchema?.lang === lang}

diff --git a/frontend/src/lib/components/copilot/lib.ts b/frontend/src/lib/components/copilot/lib.ts index 6f44a8db20..fe7028dc1e 100644 --- a/frontend/src/lib/components/copilot/lib.ts +++ b/frontend/src/lib/components/copilot/lib.ts @@ -410,7 +410,7 @@ function addDBSChema(scriptOptions: CopilotOptions, prompt: string) { const { dbSchema, language } = scriptOptions if ( dbSchema && - ['postgresql', 'mysql', 'snowflake', 'bigquery', 'mssql', 'graphql'].includes(language) && // make sure we are using a SQL/query language + ['postgresql', 'mysql', 'snowflake', 'bigquery', 'mssql', 'graphql', 'oracledb'].includes(language) && // make sure we are using a SQL/query language language === dbSchema.lang // make sure we are using the same language as the schema ) { let { stringified } = dbSchema diff --git a/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte b/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte index 6658e1d299..31330d1c34 100644 --- a/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte +++ b/frontend/src/lib/components/flows/content/FlowInputsQuick.svelte @@ -125,7 +125,7 @@ let inlineScripts: [string, SupportedLanguage | 'docker'][] = [] - const enterpriseLangs = ['bigquery', 'snowflake', 'mssql'] + const enterpriseLangs = ['bigquery', 'snowflake', 'mssql', 'oracledb'] function computeInlineScriptChoices( funcDesc: string, diff --git a/frontend/src/lib/components/flows/pickers/FlowScriptPicker.svelte b/frontend/src/lib/components/flows/pickers/FlowScriptPicker.svelte index 78ccb80e83..8bc4e92075 100644 --- a/frontend/src/lib/components/flows/pickers/FlowScriptPicker.svelte +++ b/frontend/src/lib/components/flows/pickers/FlowScriptPicker.svelte @@ -11,7 +11,7 @@ export let id: string | undefined = undefined - const enterpriseLangs = ['bigquery', 'snowflake', 'mssql'] + const enterpriseLangs = ['bigquery', 'snowflake', 'mssql', 'oracledb'] diff --git a/frontend/src/lib/components/icons/OracleDBIcon.svelte b/frontend/src/lib/components/icons/OracleDBIcon.svelte new file mode 100644 index 0000000000..86dc7ba47c --- /dev/null +++ b/frontend/src/lib/components/icons/OracleDBIcon.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/frontend/src/lib/components/icons/index.ts b/frontend/src/lib/components/icons/index.ts index cc2dce5050..adc460624b 100644 --- a/frontend/src/lib/components/icons/index.ts +++ b/frontend/src/lib/components/icons/index.ts @@ -63,6 +63,7 @@ import RssIcon from './RssIcon.svelte' import ShopifyIcon from './ShopifyIcon.svelte' import TypeformIcon from './TypeformIcon.svelte' import BigQueryIcon from './BigQueryIcon.svelte' +import OracleDBIcon from './OracleDBIcon.svelte' import GraphqlIcon from './GraphqlIcon.svelte' import NocoDbIcon from './NocoDbIcon.svelte' import AzureIcon from './AzureIcon.svelte' @@ -164,6 +165,7 @@ export const APP_TO_ICON_COMPONENT = { shopify: ShopifyIcon, typeform: TypeformIcon, bigquery: BigQueryIcon, + oracledb: OracleDBIcon, graphql: GraphqlIcon, nocodb: NocoDbIcon, azure: AzureIcon, @@ -260,6 +262,7 @@ export { ShopifyIcon, TypeformIcon, BigQueryIcon, + OracleDBIcon, GraphqlIcon, NocoDbIcon, AzureIcon, diff --git a/frontend/src/lib/consts.ts b/frontend/src/lib/consts.ts index 45ccb51978..5070c1bb1d 100644 --- a/frontend/src/lib/consts.ts +++ b/frontend/src/lib/consts.ts @@ -115,6 +115,24 @@ export const MYSQL_TYPES = [ 'time' ] +export const ORACLEDB_TYPES = [ + 'varchar2', + 'char', + 'nchar', + 'nvarchar2', + 'clob', + 'nclob', + 'blob', + 'number', + 'float', + 'binary_float', + 'binary_double', + 'date', + 'timestamp', + 'long', + 'rowid', + 'urowid' +] export const BIGQUERY_TYPES = [ 'string', 'string[]', diff --git a/frontend/src/lib/infer.ts b/frontend/src/lib/infer.ts index 604ee9802c..0e1ab2bc77 100644 --- a/frontend/src/lib/infer.ts +++ b/frontend/src/lib/infer.ts @@ -8,6 +8,7 @@ import initTsParser, { parse_deno, parse_outputs } from 'windmill-parser-wasm-ts import initRegexParsers, { parse_sql, parse_mysql, + parse_oracledb, parse_bigquery, parse_snowflake, parse_graphql, @@ -85,7 +86,7 @@ export async function inferArgs( } let inlineDBResource: string | undefined = undefined - if (['postgresql', 'mysql', 'bigquery', 'snowflake', 'mssql'].includes(language ?? '')) { + if (['postgresql', 'mysql', 'bigquery', 'snowflake', 'mssql', 'oracledb'].includes(language ?? '')) { await initWasmRegex() inlineDBResource = parse_db_resource(code) } @@ -128,6 +129,14 @@ export async function inferArgs( ...inferedSchema.args ] } + } else if (language == 'oracledb') { + inferedSchema = JSON.parse(parse_oracledb(code)) + if (inlineDBResource === undefined) { + inferedSchema.args = [ + { name: 'database', typ: { resource: 'oracledb' } }, + ...inferedSchema.args + ] + } } else if (language == 'snowflake') { inferedSchema = JSON.parse(parse_snowflake(code)) if (inlineDBResource === undefined) { diff --git a/frontend/src/lib/script_helpers.ts b/frontend/src/lib/script_helpers.ts index 5b99f3cf96..fdb68b5610 100644 --- a/frontend/src/lib/script_helpers.ts +++ b/frontend/src/lib/script_helpers.ts @@ -267,6 +267,14 @@ INSERT INTO \`demodb.demo\` VALUES (@name1, @name2, @name3); UPDATE \`demodb.demo\` SET col2 = @name4 WHERE col2 = @name2; ` +const ORACLEDB_INIT_CODE = `-- to pin the database use '-- database f/your/path' +-- :name1 (text) = default arg +-- :name2 (int) +-- :name3 (int) +INSERT INTO demo VALUES (:name1, :name2); +UPDATE demo SET col2 = :name3 WHERE col2 = :name2; +` + const SNOWFLAKE_INIT_CODE = `-- to pin the database use '-- database f/your/path' -- ? name1 (varchar) = default arg -- ? name2 (int) @@ -838,6 +846,9 @@ export const INITIAL_CODE = { graphql: { script: GRAPHQL_INIT_CODE }, + oracledb: { + script: ORACLEDB_INIT_CODE + }, php: { script: PHP_INIT_CODE }, @@ -942,6 +953,8 @@ export function initialCode( return INITIAL_CODE.mysql.script } else if (language == 'bigquery') { return INITIAL_CODE.bigquery.script + } else if (language == 'oracledb') { + return INITIAL_CODE.oracledb.script } else if (language == 'snowflake') { return INITIAL_CODE.snowflake.script } else if (language == 'mssql') { diff --git a/frontend/src/lib/scripts.ts b/frontend/src/lib/scripts.ts index dcbb1dfc1c..f1acf854cd 100644 --- a/frontend/src/lib/scripts.ts +++ b/frontend/src/lib/scripts.ts @@ -21,6 +21,8 @@ export function scriptLangToEditorLang( return 'sql' } else if (lang == 'bigquery') { return 'sql' + } else if (lang == 'oracledb') { + return 'sql' } else if (lang == 'snowflake') { return 'sql' } else if (lang == 'mssql') { @@ -111,6 +113,7 @@ const scriptLanguagesArray: [SupportedLanguage | 'docker' | 'bunnative', string] ['postgresql', 'PostgreSQL'], ['mysql', 'MySQL'], ['bigquery', 'BigQuery'], + ['oracledb', 'Oracle Database'], ['snowflake', 'Snowflake'], ['mssql', 'MS SQL Server'], ['graphql', 'GraphQL'], diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts index 65ba9f44ef..ad02151f41 100644 --- a/frontend/src/lib/stores.ts +++ b/frontend/src/lib/stores.ts @@ -110,7 +110,7 @@ type SQLBaseSchema = { } export interface SQLSchema { - lang: 'mysql' | 'bigquery' | 'postgresql' | 'snowflake' | 'mssql' + lang: 'mysql' | 'bigquery' | 'postgresql' | 'snowflake' | 'mssql' | 'oracledb' schema: SQLBaseSchema publicOnly: boolean | undefined stringified: string diff --git a/frontend/src/routes/(root)/(logged)/run/[...run]/+page.svelte b/frontend/src/routes/(root)/(logged)/run/[...run]/+page.svelte index 6310a14fcf..4a7a8e2280 100644 --- a/frontend/src/routes/(root)/(logged)/run/[...run]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/run/[...run]/+page.svelte @@ -732,7 +732,7 @@ priority: {job.priority}

{/if} - {#if job.tag && !['deno', 'python3', 'flow', 'other', 'go', 'postgresql', 'mysql', 'bigquery', 'snowflake', 'mssql', 'graphql', 'nativets', 'bash', 'powershell', 'php', 'rust', 'other', 'ansible', 'csharp', 'dependency'].includes(job.tag)} + {#if job.tag && !['deno', 'python3', 'flow', 'other', 'go', 'postgresql', 'mysql', 'bigquery', 'snowflake', 'mssql', 'graphql', 'oracledb', 'nativets', 'bash', 'powershell', 'php', 'rust', 'other', 'ansible', 'csharp', 'dependency'].includes(job.tag)}
Tag: {job.tag}