Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Enterprise-grade relationale Datenbank",
|
||||
"Connection Type": "Verbindungstyp",
|
||||
"Host": "Host",
|
||||
"Port": "Port",
|
||||
"Service Name": "Dienstname",
|
||||
"Connection String": "Verbindungszeichenkette",
|
||||
"Username": "Benutzername",
|
||||
"Password": "Kennwort",
|
||||
"How you want to connect": "Wie Sie sich verbinden möchten",
|
||||
"Database server hostname or IP": "Hostname oder IP des Datenbankservers",
|
||||
"Database port": "Datenbank-Port",
|
||||
"Oracle service name": "Oracle-Dienstname",
|
||||
"Full connection string (e.g., host:port/serviceName)": "Kompletter Verbindungsstring (z.B. host:port/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Verbinden Sie sich mit Oracle-Datenbank entweder mit einem Service-Namen (Host/Port/Service) oder einem vollständigen Verbindungs-String.",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Benutzerdefiniertes SQL ausführen",
|
||||
"Update Row": "Zeile aktualisieren",
|
||||
"Delete Row": "Zeile löschen",
|
||||
"Find Row": "Finde Zeile",
|
||||
"Insert a row into an Oracle table": "Eine Zeile in eine Oracle-Tabelle einfügen",
|
||||
"Insert multiple rows into an Oracle table": "Mehrere Zeilen in eine Oracle-Tabelle einfügen",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Benutzerdefiniertes SQL oder PL/SQL in Oracle ausführen",
|
||||
"Update rows in an Oracle table": "Aktualisiere Zeilen in einer Oracle-Tabelle",
|
||||
"Delete rows from an Oracle table": "Datensätze aus einer Oracle-Tabelle löschen",
|
||||
"Find rows in an Oracle table": "Datensätze in einer Oracle-Tabelle finden",
|
||||
"Table Name": "Tabellenname",
|
||||
"Row": "Zeile",
|
||||
"Rows": "Zeilen",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "SQL-Abfrage",
|
||||
"Bind Parameters": "Verbindungsparameter",
|
||||
"Values": "Werte",
|
||||
"Filter (WHERE)": "Filter (WHERE)",
|
||||
"Column names and values to insert": "Spaltennamen und Werte zum Einfügen",
|
||||
"Array of objects with column names and values": "Array von Objekten mit Spaltennamen und Werten",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**NICHT** Fügen Sie dynamische Eingaben direkt in die Abfrage ein. Verwenden Sie Bind Parameter (:param), um **SQL Injection** zu verhindern.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL oder PL/SQL zum Ausführen. Verwenden Sie :param für Bind-Parameter.",
|
||||
"Key-value pairs for bind variables": "Schlüssel-Wert-Paare für Bind-Variablen",
|
||||
"Column names and new values to set": "Spaltennamen und neue zu setzende Werte",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Bedingungen für Zeilen. Leeres Objekt aktualisiert ALLE Zeilen.",
|
||||
"Conditions to match rows for deletion": "Bedingungen für die Löschung der Zeilen",
|
||||
"Conditions to match rows": "Bedingungen für Zeilen übereinstimmen",
|
||||
"New Row": "Neue Zeile",
|
||||
"Triggers when a new row is created": "Wird ausgelöst, wenn eine neue Zeile erstellt wird",
|
||||
"Order By Column": "Nach Spalte bestellen",
|
||||
"Order Direction": "Bestellrichtung",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**HINWEIS:** Holt die neuesten Zeilen mit der Bestellspalte (neueste zuerst) und fragt dann nach neuen Zeilen.",
|
||||
"Column that increases over time (ID or timestamp)": "Spalte, die im Laufe der Zeit steigt (ID oder Zeitstempel)",
|
||||
"Sort direction to fetch newest rows first": "Sortierrichtung, um die neuesten Zeilen zuerst zu holen",
|
||||
"Ascending": "Aufsteigend",
|
||||
"Descending": "Absteigend"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Base de datos relacional de grado empresarial",
|
||||
"Connection Type": "Tipo de conexión",
|
||||
"Host": "Anfitrión",
|
||||
"Port": "Puerto",
|
||||
"Service Name": "Nombre del servicio",
|
||||
"Connection String": "Cadena de conexión",
|
||||
"Username": "Usuario",
|
||||
"Password": "Contraseña",
|
||||
"How you want to connect": "Cómo quieres conectar",
|
||||
"Database server hostname or IP": "Servidor de base de datos o IP",
|
||||
"Database port": "Puerto de base de datos",
|
||||
"Oracle service name": "Nombre del servicio Oracle",
|
||||
"Full connection string (e.g., host:port/serviceName)": "Cadena de conexión completa (por ejemplo, host:port/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Conéctate a Oracle Database usando un nombre de servicio (host/puerto/servicio) o una cadena de conexión completa.",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Ejecutar SQL personalizado",
|
||||
"Update Row": "Actualizar fila",
|
||||
"Delete Row": "Eliminar fila",
|
||||
"Find Row": "Buscar fila",
|
||||
"Insert a row into an Oracle table": "Inserta una fila en una tabla Oracle",
|
||||
"Insert multiple rows into an Oracle table": "Insertar múltiples filas en una tabla Oracle",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Ejecutar SQL o PL/SQL personalizado en Oracle",
|
||||
"Update rows in an Oracle table": "Actualizar registros en una tabla Oracle",
|
||||
"Delete rows from an Oracle table": "Eliminar filas de una tabla Oracle",
|
||||
"Find rows in an Oracle table": "Buscar registros en una tabla Oracle",
|
||||
"Table Name": "Nombre de tabla",
|
||||
"Row": "Fila",
|
||||
"Rows": "Filas",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "Consulta SQL",
|
||||
"Bind Parameters": "Parámetros de enlace",
|
||||
"Values": "Valores",
|
||||
"Filter (WHERE)": "Filtrar (WHERE)",
|
||||
"Column names and values to insert": "Nombres y valores de columna a insertar",
|
||||
"Array of objects with column names and values": "Matriz de objetos con nombres y valores de columna",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**NO** inserta entrada dinámica directamente en la consulta. Use parámetros de enlace (:param) para prevenir la **inyección SQL**.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL o PL/SQL para ejecutar. Utilice :param para parámetros de enlace.",
|
||||
"Key-value pairs for bind variables": "Pares de clave-valor para variables de enlace",
|
||||
"Column names and new values to set": "Nombres de columnas y nuevos valores a establecer",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Condiciones para coincidir con las filas. El objeto vacío actualiza TODAS las filas.",
|
||||
"Conditions to match rows for deletion": "Condiciones para coincidir con las filas para su eliminación",
|
||||
"Conditions to match rows": "Condiciones para coincidir filas",
|
||||
"New Row": "Nueva fila",
|
||||
"Triggers when a new row is created": "Desencadena cuando se crea una nueva fila",
|
||||
"Order By Column": "Ordenar por columna",
|
||||
"Order Direction": "Dirección del pedido",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**NOTA:** Obtiene las últimas filas usando la columna de orden (más reciente primero), luego sigue leyendo las filas nuevas.",
|
||||
"Column that increases over time (ID or timestamp)": "Columna que aumenta con el tiempo (ID o marca de tiempo)",
|
||||
"Sort direction to fetch newest rows first": "Ordenar la dirección para obtener las filas más recientes primero",
|
||||
"Ascending": "Ascendiente",
|
||||
"Descending": "Descendiente"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Base de données relationnelle de niveau entreprise",
|
||||
"Connection Type": "Type de connexion",
|
||||
"Host": "Hôte",
|
||||
"Port": "Port",
|
||||
"Service Name": "Nom du service",
|
||||
"Connection String": "Chaîne de connexion",
|
||||
"Username": "Nom d'utilisateur",
|
||||
"Password": "Password",
|
||||
"How you want to connect": "Comment vous voulez vous connecter",
|
||||
"Database server hostname or IP": "Nom d'hôte ou IP du serveur de base de données",
|
||||
"Database port": "Port de la base de données",
|
||||
"Oracle service name": "Nom du service Oracle",
|
||||
"Full connection string (e.g., host:port/serviceName)": "Chaîne de connexion complète (par exemple, hôte:port/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Connectez-vous à la base de données Oracle en utilisant soit le nom du service (hôte/port/service) soit une chaîne de connexion complète.",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Exécuter SQL personnalisé",
|
||||
"Update Row": "Mettre à jour la ligne",
|
||||
"Delete Row": "Supprimer la ligne",
|
||||
"Find Row": "Trouver une ligne",
|
||||
"Insert a row into an Oracle table": "Insérer une ligne dans une table Oracle",
|
||||
"Insert multiple rows into an Oracle table": "Insérer plusieurs lignes dans une table Oracle",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Exécuter SQL personnalisé ou PL/SQL dans Oracle",
|
||||
"Update rows in an Oracle table": "Mettre à jour les lignes dans une table Oracle",
|
||||
"Delete rows from an Oracle table": "Supprimer les lignes d'une table Oracle",
|
||||
"Find rows in an Oracle table": "Trouver des lignes dans une table Oracle",
|
||||
"Table Name": "Nom de la table",
|
||||
"Row": "Ligne",
|
||||
"Rows": "Lignes",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "Requête SQL",
|
||||
"Bind Parameters": "Lier les paramètres",
|
||||
"Values": "Valeurs",
|
||||
"Filter (WHERE)": "Filtrer (WHERE)",
|
||||
"Column names and values to insert": "Noms de colonnes et valeurs à insérer",
|
||||
"Array of objects with column names and values": "Tableau d'objets avec des noms de colonnes et des valeurs",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**NE PAS INS** insérer une entrée dynamique directement dans la requête. Utilisez les paramètres de liaison (:param) pour éviter **l'injection SQL**.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL ou PL/SQL à exécuter. Utilisez :param pour lier les paramètres.",
|
||||
"Key-value pairs for bind variables": "Paires clé-valeur pour les variables liées",
|
||||
"Column names and new values to set": "Noms de colonnes et nouvelles valeurs à définir",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Conditions de recherche des lignes. L'objet vide met à jour TOUTES les lignes.",
|
||||
"Conditions to match rows for deletion": "Conditions de recherche des lignes pour la suppression",
|
||||
"Conditions to match rows": "Conditions de correspondance des lignes",
|
||||
"New Row": "Nouvelle ligne",
|
||||
"Triggers when a new row is created": "Déclenche quand une nouvelle ligne est créée",
|
||||
"Order By Column": "Trier par colonne",
|
||||
"Order Direction": "Direction de la commande",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**REMARQUE :** Récupère les dernières lignes en utilisant la colonne d'ordre (plus récent en premier), puis continue de voter pour les nouvelles lignes.",
|
||||
"Column that increases over time (ID or timestamp)": "Colonne qui augmente au fil du temps (ID ou horodatage)",
|
||||
"Sort direction to fetch newest rows first": "Trier la direction pour récupérer les dernières lignes en premier",
|
||||
"Ascending": "Ascendant",
|
||||
"Descending": "Descendant"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "エンタープライズグレードのリレーショナルデータベース",
|
||||
"Connection Type": "接続タイプ",
|
||||
"Host": "ホスト",
|
||||
"Port": "ポート",
|
||||
"Service Name": "サービス名",
|
||||
"Connection String": "接続文字列",
|
||||
"Username": "ユーザー名",
|
||||
"Password": "Password",
|
||||
"How you want to connect": "接続方法",
|
||||
"Database server hostname or IP": "データベースサーバーのホスト名または IP",
|
||||
"Database port": "データベースポート",
|
||||
"Oracle service name": "Oracle サービス名",
|
||||
"Full connection string (e.g., host:port/serviceName)": "完全な接続文字列 (例: host:port/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "サービス名 (ホスト/ポート/サービス) または完全な接続文字列を使用して、Oracle Databaseに接続します。",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "カスタム SQL を実行",
|
||||
"Update Row": "行を更新",
|
||||
"Delete Row": "行を削除",
|
||||
"Find Row": "行を検索",
|
||||
"Insert a row into an Oracle table": "Oracleテーブルに行を挿入",
|
||||
"Insert multiple rows into an Oracle table": "Oracleテーブルに複数の行を挿入",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Oracle でカスタム SQL または PL/SQL を実行します",
|
||||
"Update rows in an Oracle table": "Oracleテーブルの行を更新",
|
||||
"Delete rows from an Oracle table": "Oracleテーブルから行を削除",
|
||||
"Find rows in an Oracle table": "Oracleテーブルの行を検索",
|
||||
"Table Name": "テーブル名",
|
||||
"Row": "行",
|
||||
"Rows": "行",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "SQL クエリ",
|
||||
"Bind Parameters": "パラメータのバインド",
|
||||
"Values": "値",
|
||||
"Filter (WHERE)": "フィルター (WHERE)",
|
||||
"Column names and values to insert": "挿入する列名と値",
|
||||
"Array of objects with column names and values": "列名と値を持つオブジェクトの配列",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**クエリに直接動的入力を挿入しないでください** **SQLインジェクション**を防ぐためにバインドパラメータ(:param)を使用してください。",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQLまたはPL/SQLを実行します。バインドパラメータに:paramを使用します。",
|
||||
"Key-value pairs for bind variables": "バインド変数のキーと値のペア",
|
||||
"Column names and new values to set": "設定する列名と新しい値",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "行と一致する条件。空のオブジェクトはすべての行を更新します。",
|
||||
"Conditions to match rows for deletion": "削除のための行を一致させる条件",
|
||||
"Conditions to match rows": "行に一致する条件",
|
||||
"New Row": "新しい行",
|
||||
"Triggers when a new row is created": "新しい行が作成されたときにトリガーします",
|
||||
"Order By Column": "並び順",
|
||||
"Order Direction": "注文の方向",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**注意:** 順序列(最初に最新)を使って最新の行をフェッチし、新しい行のポーリングを続けます。",
|
||||
"Column that increases over time (ID or timestamp)": "時間の経過とともに増加する列(IDまたはタイムスタンプ)",
|
||||
"Sort direction to fetch newest rows first": "最新の行を最初に取得するためのソート方向",
|
||||
"Ascending": "昇順",
|
||||
"Descending": "降順"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Enterprise-grade relationele database",
|
||||
"Connection Type": "Type verbinding",
|
||||
"Host": "Hostnaam",
|
||||
"Port": "Poort",
|
||||
"Service Name": "Service Naam",
|
||||
"Connection String": "Connectie String",
|
||||
"Username": "Gebruikersnaam",
|
||||
"Password": "Wachtwoord",
|
||||
"How you want to connect": "Hoe u verbinding wilt maken",
|
||||
"Database server hostname or IP": "Hostnaam van databaseserver of IP",
|
||||
"Database port": "Database poort",
|
||||
"Oracle service name": "Oracle servicenaam",
|
||||
"Full connection string (e.g., host:port/serviceName)": "Volledige connectie string (bijv. host:poort/servicenaam)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Maak verbinding met Oracle Database met behulp van een servicenaam (host/poort/service) of een volledige verbinding string.",
|
||||
"Insert Row": "Rijen invoegen",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Aangepaste SQL uitvoeren",
|
||||
"Update Row": "Rij bijwerken",
|
||||
"Delete Row": "Verwijder rij",
|
||||
"Find Row": "Rij zoeken",
|
||||
"Insert a row into an Oracle table": "Plaats een rij in een Oracle tafel",
|
||||
"Insert multiple rows into an Oracle table": "Meerdere rijen invoegen in een Oracle tabel",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Aangepaste SQL of PL/SQL in Oracle uitvoeren",
|
||||
"Update rows in an Oracle table": "Rijen bijwerken in een Oracle tabel",
|
||||
"Delete rows from an Oracle table": "Rijen uit een Oracle tabel verwijderen",
|
||||
"Find rows in an Oracle table": "Vind rijen in een Oracle tafel",
|
||||
"Table Name": "Tafel naam",
|
||||
"Row": "Rij",
|
||||
"Rows": "Rijen",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "SQL query",
|
||||
"Bind Parameters": "Bind parameters",
|
||||
"Values": "Waarden",
|
||||
"Filter (WHERE)": "Filter (WHERE)",
|
||||
"Column names and values to insert": "Kolomnamen en waarden om in te voegen",
|
||||
"Array of objects with column names and values": "Array of objecten met kolomnamen en waarden",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**NIET** voeg dynamische invoer direct in de query in. Gebruik bindparameters (:param) om **SQL injectie te voorkomen**.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL of PL/SQL uit te voeren. Gebruik :param voor bind parameters.",
|
||||
"Key-value pairs for bind variables": "Sleutelwaarde paren voor bind variabelen",
|
||||
"Column names and new values to set": "Kolomnamen en nieuwe waarden om in te stellen",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Voorwaarden om rijen aan te passen. Leeg object update ALLE rijen.",
|
||||
"Conditions to match rows for deletion": "Voorwaarden om rijen af te stemmen voor verwijdering",
|
||||
"Conditions to match rows": "Voorwaarden om rijen aan te passen",
|
||||
"New Row": "Nieuwe rij",
|
||||
"Triggers when a new row is created": "Triggert wanneer een nieuwe rij wordt gemaakt",
|
||||
"Order By Column": "Op kolom sorteren",
|
||||
"Order Direction": "Order richting",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**Let op:** Fetches de nieuwste rijen met behulp van de orderkolom (nieuwste eerst), en blijft de polling voor nieuwe rijen houden.",
|
||||
"Column that increases over time (ID or timestamp)": "Kolom die verhoogt in de tijd (ID of tijdstempel)",
|
||||
"Sort direction to fetch newest rows first": "Sorteer richting om de nieuwste rijen eerst op te halen",
|
||||
"Ascending": "Oplopend",
|
||||
"Descending": "Aflopend"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Banco de dados relativo à empresa",
|
||||
"Connection Type": "Tipo de conexão",
|
||||
"Host": "Servidor",
|
||||
"Port": "Porta",
|
||||
"Service Name": "Nome do Serviço",
|
||||
"Connection String": "String de conexão",
|
||||
"Username": "Usuário:",
|
||||
"Password": "Senha",
|
||||
"How you want to connect": "Como você deseja se conectar",
|
||||
"Database server hostname or IP": "hostname do servidor de banco de dados ou IP",
|
||||
"Database port": "Porta do Banco",
|
||||
"Oracle service name": "Nome do serviço Oracle",
|
||||
"Full connection string (e.g., host:port/serviceName)": "String completa de conexão (ex.: host:porto/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Conectar à base de dados Oracle usando o Nome do Serviço (host/porta/serviço) ou uma string de conexão completa.",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Executar SQL personalizada",
|
||||
"Update Row": "Atualizar linha",
|
||||
"Delete Row": "Excluir linha",
|
||||
"Find Row": "Encontrar linha",
|
||||
"Insert a row into an Oracle table": "Inserir uma linha em uma tabela Oracle",
|
||||
"Insert multiple rows into an Oracle table": "Inserir várias linhas em uma tabela Oracle",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Executar SQL ou PL/SQL personalizado em Oracle",
|
||||
"Update rows in an Oracle table": "Atualizar linhas em uma tabela Oracle",
|
||||
"Delete rows from an Oracle table": "Excluir linhas de uma tabela Oracle",
|
||||
"Find rows in an Oracle table": "Encontre linhas em uma mesa Oracle",
|
||||
"Table Name": "Nome da Tabela",
|
||||
"Row": "Linha",
|
||||
"Rows": "Linhas",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "Consulta SQL",
|
||||
"Bind Parameters": "Parâmetros de Vinculação",
|
||||
"Values": "Valores",
|
||||
"Filter (WHERE)": "Filtro (WHERE)",
|
||||
"Column names and values to insert": "Nomes de coluna e valores para inserir",
|
||||
"Array of objects with column names and values": "Array de objetos com nomes e valores de coluna",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**NÃO** insira entrada dinâmica diretamente na consulta. Use parâmetros de vínculo (:param) para evitar **SQL injection**.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL ou PL/SQL para executar. Use :param para parâmetros de vinculação.",
|
||||
"Key-value pairs for bind variables": "Pares chave-valor para variáveis de compilação",
|
||||
"Column names and new values to set": "Nomes de coluna e novos valores para definir",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Condições para combinar linhas. Objeto vazio atualiza TODAS as linhas.",
|
||||
"Conditions to match rows for deletion": "Condições para combinar linhas para exclusão",
|
||||
"Conditions to match rows": "Condições para combinar linhas",
|
||||
"New Row": "Nova linha",
|
||||
"Triggers when a new row is created": "Dispara quando uma nova linha é criada",
|
||||
"Order By Column": "Ordenar por coluna",
|
||||
"Order Direction": "Direção da ordem",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**NOTA:** Busca linhas mais recentes usando a coluna de ordem (mais recente primeiro), então continua fazendo sondagem por novas linhas.",
|
||||
"Column that increases over time (ID or timestamp)": "Coluna que aumenta ao longo do tempo (ID ou timestamp)",
|
||||
"Sort direction to fetch newest rows first": "Ordenar direção para buscar linhas mais recentes primeiro",
|
||||
"Ascending": "Crescente",
|
||||
"Descending": "Decrescente"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Enterprise-grade relational database",
|
||||
"Connection Type": "Connection Type",
|
||||
"Host": "Host",
|
||||
"Port": "Port",
|
||||
"Service Name": "Service Name",
|
||||
"Connection String": "Connection String",
|
||||
"Username": "Username",
|
||||
"Password": "Password",
|
||||
"How you want to connect": "How you want to connect",
|
||||
"Database server hostname or IP": "Database server hostname or IP",
|
||||
"Database port": "Database port",
|
||||
"Oracle service name": "Oracle service name",
|
||||
"Full connection string (e.g., host:port/serviceName)": "Full connection string (e.g., host:port/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Run Custom SQL",
|
||||
"Update Row": "Update Row",
|
||||
"Delete Row": "Delete Row",
|
||||
"Find Row": "Find Row",
|
||||
"Insert a row into an Oracle table": "Insert a row into an Oracle table",
|
||||
"Insert multiple rows into an Oracle table": "Insert multiple rows into an Oracle table",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Execute custom SQL or PL/SQL in Oracle",
|
||||
"Update rows in an Oracle table": "Update rows in an Oracle table",
|
||||
"Delete rows from an Oracle table": "Delete rows from an Oracle table",
|
||||
"Find rows in an Oracle table": "Find rows in an Oracle table",
|
||||
"Table Name": "Table Name",
|
||||
"Row": "Row",
|
||||
"Rows": "Rows",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "SQL Query",
|
||||
"Bind Parameters": "Bind Parameters",
|
||||
"Values": "Values",
|
||||
"Filter (WHERE)": "Filter (WHERE)",
|
||||
"Column names and values to insert": "Column names and values to insert",
|
||||
"Array of objects with column names and values": "Array of objects with column names and values",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL or PL/SQL to execute. Use :param for bind parameters.",
|
||||
"Key-value pairs for bind variables": "Key-value pairs for bind variables",
|
||||
"Column names and new values to set": "Column names and new values to set",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Conditions to match rows. Empty object updates ALL rows.",
|
||||
"Conditions to match rows for deletion": "Conditions to match rows for deletion",
|
||||
"Conditions to match rows": "Conditions to match rows",
|
||||
"New Row": "New Row",
|
||||
"Triggers when a new row is created": "Triggers when a new row is created",
|
||||
"Order By Column": "Order By Column",
|
||||
"Order Direction": "Order Direction",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.",
|
||||
"Column that increases over time (ID or timestamp)": "Column that increases over time (ID or timestamp)",
|
||||
"Sort direction to fetch newest rows first": "Sort direction to fetch newest rows first",
|
||||
"Ascending": "Ascending",
|
||||
"Descending": "Descending"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"Enterprise-grade relational database": "Enterprise-grade relational database",
|
||||
"Connection Type": "Connection Type",
|
||||
"Host": "主机",
|
||||
"Port": "端口",
|
||||
"Service Name": "Service Name",
|
||||
"Connection String": "Connection String",
|
||||
"Username": "用户名",
|
||||
"Password": "Password",
|
||||
"How you want to connect": "How you want to connect",
|
||||
"Database server hostname or IP": "Database server hostname or IP",
|
||||
"Database port": "Database port",
|
||||
"Oracle service name": "Oracle service name",
|
||||
"Full connection string (e.g., host:port/serviceName)": "Full connection string (e.g., host:port/serviceName)",
|
||||
"Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.": "Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.",
|
||||
"Insert Row": "Insert Row",
|
||||
"Insert Rows": "Insert Rows",
|
||||
"Run Custom SQL": "Run Custom SQL",
|
||||
"Update Row": "更新行",
|
||||
"Delete Row": "删除行",
|
||||
"Find Row": "Find Row",
|
||||
"Insert a row into an Oracle table": "Insert a row into an Oracle table",
|
||||
"Insert multiple rows into an Oracle table": "Insert multiple rows into an Oracle table",
|
||||
"Execute custom SQL or PL/SQL in Oracle": "Execute custom SQL or PL/SQL in Oracle",
|
||||
"Update rows in an Oracle table": "Update rows in an Oracle table",
|
||||
"Delete rows from an Oracle table": "Delete rows from an Oracle table",
|
||||
"Find rows in an Oracle table": "Find rows in an Oracle table",
|
||||
"Table Name": "Table Name",
|
||||
"Row": "Row",
|
||||
"Rows": "Rows",
|
||||
"Markdown": "Markdown",
|
||||
"SQL Query": "SQL Query",
|
||||
"Bind Parameters": "Bind Parameters",
|
||||
"Values": "值",
|
||||
"Filter (WHERE)": "Filter (WHERE)",
|
||||
"Column names and values to insert": "Column names and values to insert",
|
||||
"Array of objects with column names and values": "Array of objects with column names and values",
|
||||
"**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.": "**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.",
|
||||
"SQL or PL/SQL to execute. Use :param for bind parameters.": "SQL or PL/SQL to execute. Use :param for bind parameters.",
|
||||
"Key-value pairs for bind variables": "Key-value pairs for bind variables",
|
||||
"Column names and new values to set": "Column names and new values to set",
|
||||
"Conditions to match rows. Empty object updates ALL rows.": "Conditions to match rows. Empty object updates ALL rows.",
|
||||
"Conditions to match rows for deletion": "Conditions to match rows for deletion",
|
||||
"Conditions to match rows": "Conditions to match rows",
|
||||
"New Row": "New Row",
|
||||
"Triggers when a new row is created": "Triggers when a new row is created",
|
||||
"Order By Column": "Order By Column",
|
||||
"Order Direction": "Order Direction",
|
||||
"**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.": "**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.",
|
||||
"Column that increases over time (ID or timestamp)": "Column that increases over time (ID or timestamp)",
|
||||
"Sort direction to fetch newest rows first": "Sort direction to fetch newest rows first",
|
||||
"Ascending": "升序",
|
||||
"Descending": "降序"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { oracleDbAuth } from './lib/common/auth';
|
||||
import { insertRowAction } from './lib/actions/insert-row';
|
||||
import { insertRowsAction } from './lib/actions/insert-rows';
|
||||
import { runCustomSqlAction } from './lib/actions/run-custom-sql';
|
||||
import { updateRowAction } from './lib/actions/update-row';
|
||||
import { deleteRowAction } from './lib/actions/delete-row';
|
||||
import { findRowAction } from './lib/actions/find-row';
|
||||
import { newRowTrigger } from './lib/triggers/new-row';
|
||||
|
||||
export const oracleDatabase = createPiece({
|
||||
displayName: 'Oracle Database',
|
||||
description: 'Enterprise-grade relational database',
|
||||
auth: oracleDbAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/oracle-database.png',
|
||||
categories: [PieceCategory.DEVELOPER_TOOLS],
|
||||
authors: ['Prabhukiran161', 'onyedikachi-david'],
|
||||
actions: [
|
||||
insertRowAction,
|
||||
insertRowsAction,
|
||||
runCustomSqlAction,
|
||||
updateRowAction,
|
||||
deleteRowAction,
|
||||
findRowAction,
|
||||
],
|
||||
triggers: [newRowTrigger],
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import { oracleDbProps } from '../common/props';
|
||||
|
||||
export const deleteRowAction = createAction({
|
||||
auth: oracleDbAuth,
|
||||
name: 'delete_row',
|
||||
displayName: 'Delete Row',
|
||||
description: 'Delete rows from an Oracle table',
|
||||
props: {
|
||||
tableName: oracleDbProps.tableName(),
|
||||
filter: Property.Object({
|
||||
displayName: 'Filter (WHERE)',
|
||||
description: 'Conditions to match rows for deletion',
|
||||
required: true,
|
||||
defaultValue: { ID: 101 },
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { tableName, filter } = context.propsValue;
|
||||
|
||||
if (
|
||||
typeof filter !== 'object' ||
|
||||
filter === null ||
|
||||
Array.isArray(filter)
|
||||
) {
|
||||
throw new Error('Filter must be a valid object');
|
||||
}
|
||||
|
||||
if (Object.keys(filter).length === 0) {
|
||||
throw new Error(
|
||||
'Filter cannot be empty. Use Run Custom SQL action to delete all rows.'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new OracleDbClient(context.auth.props);
|
||||
return await client.deleteRow(tableName, filter as Record<string, unknown>);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to delete rows from ${tableName}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import { oracleDbProps } from '../common/props';
|
||||
|
||||
export const findRowAction = createAction({
|
||||
auth: oracleDbAuth,
|
||||
name: 'find_row',
|
||||
displayName: 'Find Row',
|
||||
description: 'Find rows in an Oracle table',
|
||||
props: {
|
||||
tableName: oracleDbProps.tableName(),
|
||||
filter: Property.Object({
|
||||
displayName: 'Filter (WHERE)',
|
||||
description: 'Conditions to match rows',
|
||||
required: true,
|
||||
defaultValue: { ID: 101 },
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { tableName, filter } = context.propsValue;
|
||||
|
||||
if (
|
||||
typeof filter !== 'object' ||
|
||||
filter === null ||
|
||||
Array.isArray(filter)
|
||||
) {
|
||||
throw new Error('Filter must be a valid object');
|
||||
}
|
||||
|
||||
if (Object.keys(filter).length === 0) {
|
||||
throw new Error(
|
||||
'Filter cannot be empty. Use Run Custom SQL action to fetch all rows.'
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new OracleDbClient(context.auth.props);
|
||||
return await client.findRow(
|
||||
tableName,
|
||||
filter as Record<string, unknown>
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to find rows in ${tableName}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import { oracleDbProps } from '../common/props';
|
||||
|
||||
export const insertRowAction = createAction({
|
||||
auth: oracleDbAuth,
|
||||
name: 'insert_row',
|
||||
displayName: 'Insert Row',
|
||||
description: 'Insert a row into an Oracle table',
|
||||
props: {
|
||||
tableName: oracleDbProps.tableName(),
|
||||
row: Property.Object({
|
||||
displayName: 'Row',
|
||||
description: 'Column names and values to insert',
|
||||
required: true,
|
||||
defaultValue: {
|
||||
COLUMN_NAME: 'value',
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { tableName, row } = context.propsValue;
|
||||
|
||||
if (typeof row !== 'object' || row === null || Array.isArray(row)) {
|
||||
throw new Error("Row must be a valid object with column names as keys");
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new OracleDbClient(context.auth.props);
|
||||
return await client.insertRow(tableName, row as Record<string, unknown>);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to insert row into ${tableName}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import { oracleDbProps } from '../common/props';
|
||||
|
||||
export const insertRowsAction = createAction({
|
||||
auth: oracleDbAuth,
|
||||
name: 'insert_rows',
|
||||
displayName: 'Insert Rows',
|
||||
description: 'Insert multiple rows into an Oracle table',
|
||||
props: {
|
||||
tableName: oracleDbProps.tableName(),
|
||||
rows: Property.Array({
|
||||
displayName: 'Rows',
|
||||
description: 'Array of objects with column names and values',
|
||||
required: true,
|
||||
defaultValue: [
|
||||
{ COLUMN_1: 'value_a', COLUMN_2: 1 },
|
||||
{ COLUMN_1: 'value_b', COLUMN_2: 2 },
|
||||
],
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { tableName, rows } = context.propsValue;
|
||||
|
||||
if (!Array.isArray(rows) || rows.length === 0) {
|
||||
throw new Error('Rows must be a non-empty array of objects');
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new OracleDbClient(context.auth.props);
|
||||
return await client.insertRows(
|
||||
tableName,
|
||||
rows as Record<string, unknown>[]
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to insert rows into ${tableName}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import oracledb from 'oracledb';
|
||||
|
||||
export const runCustomSqlAction = createAction({
|
||||
auth: oracleDbAuth,
|
||||
name: 'run_custom_sql',
|
||||
displayName: 'Run Custom SQL',
|
||||
description: 'Execute custom SQL or PL/SQL in Oracle',
|
||||
props: {
|
||||
markdown: Property.MarkDown({
|
||||
value: `**DO NOT** insert dynamic input directly into the query. Use bind parameters (:param) to prevent **SQL injection**.`,
|
||||
}),
|
||||
sql: Property.LongText({
|
||||
displayName: 'SQL Query',
|
||||
description: 'SQL or PL/SQL to execute. Use :param for bind parameters.',
|
||||
required: true,
|
||||
defaultValue: 'SELECT * FROM employees WHERE department_id = :dept_id',
|
||||
}),
|
||||
binds: Property.Object({
|
||||
displayName: 'Bind Parameters',
|
||||
description: 'Key-value pairs for bind variables',
|
||||
required: false,
|
||||
defaultValue: { dept_id: 90 },
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { sql, binds } = context.propsValue;
|
||||
|
||||
try {
|
||||
const client = new OracleDbClient(context.auth.props);
|
||||
const bindParams = (binds as oracledb.BindParameters) || {};
|
||||
return await client.execute(sql, bindParams);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to execute SQL: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import { oracleDbProps } from '../common/props';
|
||||
|
||||
export const updateRowAction = createAction({
|
||||
auth: oracleDbAuth,
|
||||
name: 'update_row',
|
||||
displayName: 'Update Row',
|
||||
description: 'Update rows in an Oracle table',
|
||||
props: {
|
||||
tableName: oracleDbProps.tableName(),
|
||||
values: Property.Object({
|
||||
displayName: 'Values',
|
||||
description: 'Column names and new values to set',
|
||||
required: true,
|
||||
defaultValue: { SALARY: 8000 },
|
||||
}),
|
||||
filter: Property.Object({
|
||||
displayName: 'Filter (WHERE)',
|
||||
description: 'Conditions to match rows. Empty object updates ALL rows.',
|
||||
required: true,
|
||||
defaultValue: { ID: 101 },
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { tableName, values, filter } = context.propsValue;
|
||||
|
||||
if (
|
||||
typeof values !== 'object' ||
|
||||
values === null ||
|
||||
Array.isArray(values) ||
|
||||
Object.keys(values).length === 0
|
||||
) {
|
||||
throw new Error('Values must be a non-empty object');
|
||||
}
|
||||
if (
|
||||
typeof filter !== 'object' ||
|
||||
filter === null ||
|
||||
Array.isArray(filter)
|
||||
) {
|
||||
throw new Error('Filter must be a valid object');
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new OracleDbClient(context.auth.props);
|
||||
return await client.updateRow(
|
||||
tableName,
|
||||
values as Record<string, unknown>,
|
||||
filter as Record<string, unknown>
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to update rows in ${tableName}: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
import {
|
||||
PieceAuth,
|
||||
Property,
|
||||
StaticPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import oracledb from 'oracledb';
|
||||
|
||||
try {
|
||||
oracledb.initOracleClient();
|
||||
} catch (e) {
|
||||
console.log('Oracle client already initialized or failed to initialize.');
|
||||
}
|
||||
|
||||
export const oracleDbAuth = PieceAuth.CustomAuth({
|
||||
description: `Connect to Oracle Database using either Service Name (host/port/service) or a full connection string.`,
|
||||
required: true,
|
||||
props: {
|
||||
connectionType: Property.StaticDropdown({
|
||||
displayName: 'Connection Type',
|
||||
description: 'How you want to connect',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Service Name', value: 'serviceName' },
|
||||
{ label: 'Connection String', value: 'connectionString' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'serviceName',
|
||||
}),
|
||||
host: Property.ShortText({
|
||||
displayName: 'Host',
|
||||
description: 'Database server hostname or IP',
|
||||
required: false,
|
||||
}),
|
||||
port: Property.Number({
|
||||
displayName: 'Port',
|
||||
description: 'Database port',
|
||||
required: false,
|
||||
defaultValue: 1521,
|
||||
}),
|
||||
serviceName: Property.ShortText({
|
||||
displayName: 'Service Name',
|
||||
description: 'Oracle service name',
|
||||
required: false,
|
||||
}),
|
||||
connectionString: Property.LongText({
|
||||
displayName: 'Connection String',
|
||||
description: 'Full connection string (e.g., host:port/serviceName)',
|
||||
required: false,
|
||||
}),
|
||||
user: Property.ShortText({
|
||||
displayName: 'Username',
|
||||
required: true,
|
||||
}),
|
||||
password: PieceAuth.SecretText({
|
||||
displayName: 'Password',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
|
||||
validate: async ({ auth }) => {
|
||||
let connection: oracledb.Connection | undefined;
|
||||
const typedAuth = auth as StaticPropsValue<(typeof oracleDbAuth)['props']>;
|
||||
|
||||
try {
|
||||
let connectString: string | undefined;
|
||||
|
||||
if (typedAuth.connectionType === 'serviceName') {
|
||||
if (!typedAuth.host || !typedAuth.port || !typedAuth.serviceName) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Host, Port, and Service Name are required for this connection type.',
|
||||
};
|
||||
}
|
||||
connectString = `${typedAuth.host}:${typedAuth.port}/${typedAuth.serviceName}`;
|
||||
} else {
|
||||
if (!typedAuth.connectionString) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Connection String is required for this connection type.',
|
||||
};
|
||||
}
|
||||
connectString = typedAuth.connectionString;
|
||||
}
|
||||
|
||||
connection = await oracledb.getConnection({
|
||||
user: typedAuth.user,
|
||||
password: typedAuth.password,
|
||||
connectString: connectString,
|
||||
});
|
||||
|
||||
return { valid: true };
|
||||
} catch (e) {
|
||||
return {
|
||||
valid: false,
|
||||
error: (e as Error)?.message || 'Unknown connection error.',
|
||||
};
|
||||
} finally {
|
||||
if (connection) {
|
||||
try {
|
||||
await connection.close();
|
||||
} catch (e) {
|
||||
console.error('Failed to close Oracle DB connection:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export type OracleDbAuth = StaticPropsValue<typeof oracleDbAuth.props>;
|
||||
@@ -0,0 +1,389 @@
|
||||
import { OracleDbAuth } from './types';
|
||||
import oracledb from 'oracledb';
|
||||
|
||||
interface ExecuteManyResult {
|
||||
rowsAffected?: number;
|
||||
}
|
||||
|
||||
export class OracleDbClient {
|
||||
private readonly auth: OracleDbAuth;
|
||||
private connection: oracledb.Connection | undefined;
|
||||
|
||||
constructor(auth: OracleDbAuth) {
|
||||
this.auth = auth;
|
||||
}
|
||||
|
||||
private async connect(): Promise<void> {
|
||||
const connectString =
|
||||
this.auth.connectionType === 'serviceName'
|
||||
? `${this.auth.host}:${this.auth.port}/${this.auth.serviceName}`
|
||||
: this.auth.connectionString;
|
||||
|
||||
this.connection = await oracledb.getConnection({
|
||||
user: this.auth.user,
|
||||
password: this.auth.password,
|
||||
connectString: connectString,
|
||||
});
|
||||
}
|
||||
|
||||
public async getTables(): Promise<{ label: string; value: string }[]> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const result = await this.connection.execute<{ TABLE_NAME: string }>(
|
||||
`SELECT table_name FROM user_tables ORDER BY table_name`,
|
||||
[],
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
await this.close();
|
||||
|
||||
return (
|
||||
result.rows?.map((row) => ({
|
||||
label: row.TABLE_NAME,
|
||||
value: row.TABLE_NAME,
|
||||
})) || []
|
||||
);
|
||||
}
|
||||
|
||||
public async insertRow(
|
||||
tableName: string,
|
||||
rowData: Record<string, unknown>
|
||||
): Promise<{ success: boolean; rowsAffected: number }> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const columns = Object.keys(rowData);
|
||||
const values = Object.values(rowData);
|
||||
const placeholders = columns.map((_, i) => `:${i + 1}`).join(', ');
|
||||
const quotedColumns = columns.map((c) => `"${c}"`).join(', ');
|
||||
const quotedTableName = `"${tableName}"`;
|
||||
const sql = `INSERT INTO ${quotedTableName} (${quotedColumns}) VALUES (${placeholders})`;
|
||||
|
||||
try {
|
||||
const result = await this.connection.execute(sql, values, {
|
||||
autoCommit: true,
|
||||
});
|
||||
await this.close();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
rowsAffected: result.rowsAffected || 0,
|
||||
};
|
||||
} catch (error: any) {
|
||||
await this.close();
|
||||
throw this.handleOracleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async insertRows(
|
||||
tableName: string,
|
||||
rowsData: Record<string, unknown>[]
|
||||
): Promise<{ success: boolean; rowsAffected: number }> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const columns = Object.keys(rowsData[0]);
|
||||
const quotedColumns = columns.map((c) => `"${c}"`).join(', ');
|
||||
const quotedTableName = `"${tableName}"`;
|
||||
|
||||
const placeholders = columns.map((_, i) => `:${i + 1}`).join(', ');
|
||||
const sql = `INSERT INTO ${quotedTableName} (${quotedColumns}) VALUES (${placeholders})`;
|
||||
|
||||
const bindData = rowsData.map((row) => columns.map((col) => row[col]));
|
||||
|
||||
try {
|
||||
const result = await this.connection.executeMany(sql, bindData, {
|
||||
autoCommit: true,
|
||||
});
|
||||
await this.close();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
rowsAffected: result.rowsAffected || 0,
|
||||
};
|
||||
} catch (error: any) {
|
||||
await this.close();
|
||||
throw this.handleOracleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async updateRow(
|
||||
tableName: string,
|
||||
values: Record<string, unknown>,
|
||||
filter: Record<string, unknown>
|
||||
): Promise<{ success: boolean; rowsAffected: number }> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const valueKeys = Object.keys(values);
|
||||
const filterKeys = Object.keys(filter);
|
||||
|
||||
const setClause = valueKeys.map((k) => `"${k}" = :set_${k}`).join(', ');
|
||||
|
||||
const whereClause = filterKeys
|
||||
.map((k) => `"${k}" = :whr_${k}`)
|
||||
.join(' AND ');
|
||||
|
||||
const binds: oracledb.BindParameters = {};
|
||||
|
||||
for (const key of valueKeys) {
|
||||
binds[`set_${key}`] = values[key] as any;
|
||||
}
|
||||
for (const key of filterKeys) {
|
||||
binds[`whr_${key}`] = filter[key] as any;
|
||||
}
|
||||
|
||||
let sql = `UPDATE "${tableName}" SET ${setClause}`;
|
||||
if (whereClause) {
|
||||
sql += ` WHERE ${whereClause}`;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.connection.execute(sql, binds, {
|
||||
autoCommit: true,
|
||||
});
|
||||
|
||||
await this.close();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
rowsAffected: result.rowsAffected || 0,
|
||||
};
|
||||
} catch (error: any) {
|
||||
await this.close();
|
||||
throw this.handleOracleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteRow(
|
||||
tableName: string,
|
||||
filter: Record<string, unknown>
|
||||
): Promise<{ success: boolean; rowsAffected: number }> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const filterKeys = Object.keys(filter);
|
||||
|
||||
const whereClause = filterKeys
|
||||
.map((k) => `"${k}" = :whr_${k}`)
|
||||
.join(' AND ');
|
||||
|
||||
const binds: oracledb.BindParameters = {};
|
||||
for (const key of filterKeys) {
|
||||
binds[`whr_${key}`] = filter[key] as any;
|
||||
}
|
||||
|
||||
const sql = `DELETE FROM "${tableName}" WHERE ${whereClause}`;
|
||||
|
||||
try {
|
||||
const result = await this.connection.execute(sql, binds, {
|
||||
autoCommit: true,
|
||||
});
|
||||
|
||||
await this.close();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
rowsAffected: result.rowsAffected || 0,
|
||||
};
|
||||
} catch (error: any) {
|
||||
await this.close();
|
||||
throw this.handleOracleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async findRow(
|
||||
tableName: string,
|
||||
filter: Record<string, unknown>
|
||||
): Promise<unknown[]> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const filterKeys = Object.keys(filter);
|
||||
|
||||
const whereClause = filterKeys
|
||||
.map((k) => `"${k}" = :whr_${k}`)
|
||||
.join(' AND ');
|
||||
|
||||
const binds: oracledb.BindParameters = {};
|
||||
for (const key of filterKeys) {
|
||||
binds[`whr_${key}`] = filter[key] as any;
|
||||
}
|
||||
|
||||
const sql = `SELECT * FROM "${tableName}" WHERE ${whereClause}`;
|
||||
|
||||
try {
|
||||
const result = await this.connection.execute(sql, binds, {
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
});
|
||||
|
||||
await this.close();
|
||||
return (result.rows as unknown[]) || [];
|
||||
} catch (error: any) {
|
||||
await this.close();
|
||||
throw this.handleOracleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async execute(
|
||||
sql: string,
|
||||
binds: oracledb.BindParameters
|
||||
): Promise<{ rows: unknown[]; rowsAffected?: number }> {
|
||||
await this.connect();
|
||||
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.connection.execute(sql, binds, {
|
||||
autoCommit: true,
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
});
|
||||
|
||||
await this.close();
|
||||
|
||||
return {
|
||||
rows: (result.rows as unknown[]) || [],
|
||||
rowsAffected: result.rowsAffected,
|
||||
};
|
||||
} catch (error: any) {
|
||||
await this.close();
|
||||
throw this.handleOracleError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async getNewRows(
|
||||
tableName: string,
|
||||
orderByColumn: string,
|
||||
lastValue: unknown,
|
||||
filter: Record<string, unknown>
|
||||
): Promise<Record<string, unknown>[]> {
|
||||
await this.connect();
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const filterKeys = Object.keys(filter);
|
||||
const whereConditions = filterKeys.map((k) => `"${k}" = :whr_${k}`);
|
||||
whereConditions.push(`"${orderByColumn}" > :lastValue`);
|
||||
|
||||
const whereClause = whereConditions.join(' AND ');
|
||||
|
||||
const binds: Record<string, any> = { lastValue };
|
||||
for (const key of filterKeys) {
|
||||
binds[`whr_${key}`] = filter[key];
|
||||
}
|
||||
|
||||
const sql = `SELECT * FROM "${tableName}" WHERE ${whereClause} ORDER BY "${orderByColumn}" ASC`;
|
||||
|
||||
const result = await this.connection.execute(sql, binds, {
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
});
|
||||
|
||||
await this.close();
|
||||
return result.rows as Record<string, unknown>[];
|
||||
}
|
||||
|
||||
public async getLatestRows(
|
||||
tableName: string,
|
||||
orderByColumn: string,
|
||||
filter: Record<string, unknown>
|
||||
): Promise<oracledb.Result<unknown>> {
|
||||
await this.connect();
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
|
||||
const filterKeys = Object.keys(filter);
|
||||
const whereClause = filterKeys
|
||||
.map((k) => `"${k}" = :whr_${k}`)
|
||||
.join(' AND ');
|
||||
|
||||
const binds: oracledb.BindParameters = {};
|
||||
for (const key of filterKeys) {
|
||||
binds[`whr_${key}`] = filter[key] as any;
|
||||
}
|
||||
|
||||
let sql = `SELECT * FROM "${tableName}"`;
|
||||
if (whereClause) {
|
||||
sql += ` WHERE ${whereClause}`;
|
||||
}
|
||||
sql += ` ORDER BY "${orderByColumn}" DESC FETCH FIRST 5 ROWS ONLY`;
|
||||
|
||||
const result = await this.connection.execute(sql, binds, {
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
});
|
||||
|
||||
await this.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async getColumns(
|
||||
tableName: string
|
||||
): Promise<{ label: string; value: string }[]> {
|
||||
await this.connect();
|
||||
if (!this.connection) {
|
||||
throw new Error('Database connection failed and was not established.');
|
||||
}
|
||||
const result = await this.connection.execute<{ COLUMN_NAME: string }>(
|
||||
`SELECT column_name FROM user_tab_columns WHERE table_name = :tableName ORDER BY column_id`,
|
||||
{ tableName },
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
await this.close();
|
||||
return (
|
||||
result.rows?.map((row) => ({
|
||||
label: row.COLUMN_NAME,
|
||||
value: row.COLUMN_NAME,
|
||||
})) || []
|
||||
);
|
||||
}
|
||||
|
||||
public async close(): Promise<void> {
|
||||
if (this.connection) {
|
||||
await this.connection.close();
|
||||
this.connection = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private handleOracleError(error: any): Error {
|
||||
const errorNum = error?.errorNum;
|
||||
let message = error?.message || 'Unknown Oracle error';
|
||||
|
||||
// Common Oracle error codes
|
||||
if (errorNum === 1) {
|
||||
message = `Unique constraint violated: ${message}`;
|
||||
} else if (errorNum === 2290 || errorNum === 2291 || errorNum === 2292) {
|
||||
message = `Constraint violation: ${message}`;
|
||||
} else if (errorNum === 1400) {
|
||||
message = `Required column missing: ${message}`;
|
||||
} else if (errorNum === 904 || errorNum === 942) {
|
||||
message = `Invalid column or table: ${message}`;
|
||||
} else if (errorNum === 1722) {
|
||||
message = `Invalid number format: ${message}`;
|
||||
} else if (errorNum === 12899) {
|
||||
message = `Value too large for column: ${message}`;
|
||||
}
|
||||
|
||||
return new Error(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { OracleDbClient } from './client';
|
||||
import { OracleDbAuth } from './types';
|
||||
import { oracleDbAuth } from './auth';
|
||||
|
||||
export const oracleDbProps = {
|
||||
tableName: () =>
|
||||
Property.Dropdown({
|
||||
auth: oracleDbAuth,
|
||||
displayName: 'Table Name',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async (propsValue) => {
|
||||
const auth = propsValue.auth;
|
||||
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please authenticate first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const client = new OracleDbClient(auth.props);
|
||||
const tables = await client.getTables();
|
||||
return {
|
||||
disabled: false,
|
||||
options: tables.map((table) => ({
|
||||
label: table.label,
|
||||
value: table.value,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
orderBy: () =>
|
||||
Property.Dropdown({
|
||||
auth: oracleDbAuth,
|
||||
displayName: 'Order By Column',
|
||||
description: 'Column that increases over time (ID or timestamp)',
|
||||
required: true,
|
||||
refreshers: ['tableName'],
|
||||
options: async (propsValue) => {
|
||||
const tableName = propsValue['tableName'] as string | undefined;
|
||||
const auth = propsValue.auth;
|
||||
|
||||
if (!auth || !tableName) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a table first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const client = new OracleDbClient(auth.props);
|
||||
const columns = await client.getColumns(tableName);
|
||||
return {
|
||||
disabled: false,
|
||||
options: columns.map((col: { label: string; value: string }) => ({
|
||||
label: col.label,
|
||||
value: col.value,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
import { StaticPropsValue } from '@activepieces/pieces-framework';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
|
||||
export type OracleDbAuth = StaticPropsValue<(typeof oracleDbAuth)['props']>;
|
||||
@@ -0,0 +1,130 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import crypto from 'crypto';
|
||||
import dayjs from 'dayjs';
|
||||
import { oracleDbAuth } from '../common/auth';
|
||||
import { OracleDbClient } from '../common/client';
|
||||
import { oracleDbProps } from '../common/props';
|
||||
import oracledb from 'oracledb';
|
||||
|
||||
type OrderDirection = 'ASC' | 'DESC';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof oracleDbAuth>,
|
||||
{
|
||||
tableName: string;
|
||||
orderBy: string;
|
||||
orderDirection: OrderDirection | undefined;
|
||||
}
|
||||
> = {
|
||||
strategy: DedupeStrategy.LAST_ITEM,
|
||||
items: async ({ auth, propsValue, lastItemId }) => {
|
||||
const client = new OracleDbClient(auth.props);
|
||||
await client['connect']();
|
||||
|
||||
if (!client['connection']) {
|
||||
throw new Error('Database connection failed');
|
||||
}
|
||||
|
||||
const lastItem = lastItemId as string;
|
||||
const lastOrderKey = lastItem ? lastItem.split('|')[0] : null;
|
||||
const direction = propsValue.orderDirection || 'DESC';
|
||||
|
||||
let sql: string;
|
||||
const binds: oracledb.BindParameters = {};
|
||||
|
||||
if (lastOrderKey === null) {
|
||||
sql = `SELECT * FROM "${propsValue.tableName}" ORDER BY "${propsValue.orderBy}" ${direction} FETCH FIRST 5 ROWS ONLY`;
|
||||
} else {
|
||||
const operator = direction === 'DESC' ? '>=' : '<=';
|
||||
sql = `SELECT * FROM "${propsValue.tableName}" WHERE "${propsValue.orderBy}" ${operator} :lastKey ORDER BY "${propsValue.orderBy}" ${direction}`;
|
||||
binds['lastKey'] = lastOrderKey;
|
||||
}
|
||||
|
||||
const result = await client['connection'].execute(sql, binds, {
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
});
|
||||
|
||||
await client.close();
|
||||
|
||||
const rows = (result.rows as Record<string, any>[]) || [];
|
||||
const items = rows.map((row) => {
|
||||
const rowHash = crypto
|
||||
.createHash('md5')
|
||||
.update(JSON.stringify(row))
|
||||
.digest('hex');
|
||||
const isTimestamp = dayjs(row[propsValue.orderBy]).isValid();
|
||||
const orderValue = isTimestamp
|
||||
? dayjs(row[propsValue.orderBy]).toISOString()
|
||||
: row[propsValue.orderBy];
|
||||
return {
|
||||
id: orderValue + '|' + rowHash,
|
||||
data: row,
|
||||
};
|
||||
});
|
||||
|
||||
return items;
|
||||
},
|
||||
};
|
||||
|
||||
export const newRowTrigger = createTrigger({
|
||||
auth: oracleDbAuth,
|
||||
name: 'new_row',
|
||||
displayName: 'New Row',
|
||||
description: 'Triggers when a new row is created',
|
||||
props: {
|
||||
description: Property.MarkDown({
|
||||
value: `**NOTE:** Fetches latest rows using the order column (newest first), then keeps polling for new rows.`,
|
||||
}),
|
||||
tableName: oracleDbProps.tableName(),
|
||||
orderBy: oracleDbProps.orderBy(),
|
||||
orderDirection: Property.StaticDropdown<OrderDirection>({
|
||||
displayName: 'Order Direction',
|
||||
description: 'Sort direction to fetch newest rows first',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Ascending', value: 'ASC' },
|
||||
{ label: 'Descending', value: 'DESC' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'DESC',
|
||||
}),
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
sampleData: {},
|
||||
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
auth: context.auth,
|
||||
});
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
auth: context.auth,
|
||||
});
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user