This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/master by this push:
new d904102e36 initial version for DuckDB database type. fixes #2448
new 438fcf3702 Merge pull request #2451 from bamaer/2448
d904102e36 is described below
commit d904102e369c7e646c231c561ae23899439b07c6
Author: Bart Maertens <[email protected]>
AuthorDate: Tue Feb 21 10:13:13 2023 +0100
initial version for DuckDB database type. fixes #2448
---
.../plugins/databases/duckdb-assemblies/pom.xml | 52 ++++
.../duckdb-assemblies/src/assembly/assembly.xml | 57 ++++
.../src/main/resources/version.xml | 20 ++
assemblies/plugins/databases/pom.xml | 1 +
assemblies/plugins/dist/pom.xml | 13 +
docs/hop-user-manual/modules/ROOT/nav.adoc | 3 +-
.../ROOT/pages/database/databases/duckdb.adoc | 39 +++
integration-tests/duckdb/dev-env-config.json | 7 +
integration-tests/duckdb/duckdb-read.hpl | 204 +++++++++++++++
integration-tests/duckdb/duckdb-write.hpl | 156 +++++++++++
integration-tests/duckdb/hop-config.json | 290 +++++++++++++++++++++
.../duckdb/main-0001-read-write-duckdb.hwf | 159 +++++++++++
.../metadata/pipeline-run-configuration/local.json | 21 ++
.../duckdb/metadata/rdbms/duckdb.json | 26 ++
.../metadata/workflow-run-configuration/local.json | 11 +
integration-tests/duckdb/project-config.json | 13 +
plugins/databases/duckdb/pom.xml | 42 +++
.../hop/databases/duckdb/DuckDBDatabaseMeta.java | 162 ++++++++++++
plugins/databases/pom.xml | 1 +
19 files changed, 1276 insertions(+), 1 deletion(-)
diff --git a/assemblies/plugins/databases/duckdb-assemblies/pom.xml
b/assemblies/plugins/databases/duckdb-assemblies/pom.xml
new file mode 100644
index 0000000000..d23c65ab79
--- /dev/null
+++ b/assemblies/plugins/databases/duckdb-assemblies/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>hop-assemblies-plugins-databases</artifactId>
+ <groupId>org.apache.hop</groupId>
+ <version>2.4.0-SNAPSHOT</version>
+ </parent>
+
+
+ <artifactId>hop-assemblies-plugins-databases-duckdb</artifactId>
+ <version>2.4.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Hop Assemblies Plugins Databases DuckDB</name>
+ <description />
+
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.hop</groupId>
+ <artifactId>hop-databases-duckdb</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.duckdb</groupId>
+ <artifactId>duckdb_jdbc</artifactId>
+ <version>0.7.0</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git
a/assemblies/plugins/databases/duckdb-assemblies/src/assembly/assembly.xml
b/assemblies/plugins/databases/duckdb-assemblies/src/assembly/assembly.xml
new file mode 100644
index 0000000000..90b02f184a
--- /dev/null
+++ b/assemblies/plugins/databases/duckdb-assemblies/src/assembly/assembly.xml
@@ -0,0 +1,57 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
http://maven.apache.org/xsd/assembly-1.1.3.xsd">
+ <id>hop-assemblies-plugins-databases-duckdb</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <baseDirectory>databases/duckdb</baseDirectory>
+ <files>
+ <file>
+ <source>${project.basedir}/src/main/resources/version.xml</source>
+ <outputDirectory>.</outputDirectory>
+ <filtered>true</filtered>
+ </file>
+ </files>
+ <fileSets>
+ <fileSet>
+ <outputDirectory>lib</outputDirectory>
+ <excludes>
+ <exclude>**/*</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>false</useProjectArtifact>
+ <includes>
+ <include>org.apache.hop:hop-databases-duckdb:jar</include>
+ </includes>
+ </dependencySet>
+ <dependencySet>
+ <useProjectArtifact>false</useProjectArtifact>
+ <outputDirectory>lib</outputDirectory>
+ <includes>
+ <include>org.duckdb:duckdb_jdbc:jar</include>
+ </includes>
+ </dependencySet>
+ </dependencySets>
+</assembly>
diff --git
a/assemblies/plugins/databases/duckdb-assemblies/src/main/resources/version.xml
b/assemblies/plugins/databases/duckdb-assemblies/src/main/resources/version.xml
new file mode 100644
index 0000000000..6be576acae
--- /dev/null
+++
b/assemblies/plugins/databases/duckdb-assemblies/src/main/resources/version.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<version>${project.version}</version>
\ No newline at end of file
diff --git a/assemblies/plugins/databases/pom.xml
b/assemblies/plugins/databases/pom.xml
index 68ac86d7f0..285563cbfc 100644
--- a/assemblies/plugins/databases/pom.xml
+++ b/assemblies/plugins/databases/pom.xml
@@ -49,6 +49,7 @@
<module>infobright-assemblies</module>
<module>infinidb-assemblies</module>
<module>derby-assemblies</module>
+ <module>duckdb-assemblies</module>
<module>monetdb-assemblies</module>
<module>cache-assemblies</module>
<module>exasol4-assemblies</module>
diff --git a/assemblies/plugins/dist/pom.xml b/assemblies/plugins/dist/pom.xml
index 311a8d3cb9..7d0fb94700 100644
--- a/assemblies/plugins/dist/pom.xml
+++ b/assemblies/plugins/dist/pom.xml
@@ -2925,6 +2925,19 @@
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.hop</groupId>
+ <artifactId>hop-assemblies-plugins-databases-duckdb</artifactId>
+ <version>${project.version}</version>
+ <type>zip</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
<dependency>
<groupId>org.apache.hop</groupId>
<artifactId>hop-assemblies-plugins-databases-exasol4</artifactId>
diff --git a/docs/hop-user-manual/modules/ROOT/nav.adoc
b/docs/hop-user-manual/modules/ROOT/nav.adoc
index eccf11c3a9..26a44008ec 100644
--- a/docs/hop-user-manual/modules/ROOT/nav.adoc
+++ b/docs/hop-user-manual/modules/ROOT/nav.adoc
@@ -357,12 +357,13 @@ under the License.
* xref:database/databases.adoc[Relational Database Connections]
//::=START AUTO GENERATED LINKS DATABASES
** xref:database/databases/derby.adoc[Apache Derby]
-** xref:database/databases/doris.adoc[Apache Doris]
+** xref:database/databases/duckdb.adoc[DuckDB]
** xref:database/databases/apache-hive.adoc[Apache Hive]
** xref:database/databases/as400.adoc[AS400]
** xref:database/databases/cache.adoc[Cache]
** xref:database/databases/clickhouse.adoc[ClickHouse]
** xref:database/databases/db2.adoc[DB2]
+** xref:database/databases/doris.adoc[Apache Doris]
** xref:database/databases/exasol.adoc[Exasol]
** xref:database/databases/firebird.adoc[Firebird]
** xref:database/databases/googlebigquery.adoc[Google BigQuery]
diff --git
a/docs/hop-user-manual/modules/ROOT/pages/database/databases/duckdb.adoc
b/docs/hop-user-manual/modules/ROOT/pages/database/databases/duckdb.adoc
new file mode 100644
index 0000000000..467af8c330
--- /dev/null
+++ b/docs/hop-user-manual/modules/ROOT/pages/database/databases/duckdb.adoc
@@ -0,0 +1,39 @@
+////
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+////
+[[database-plugins-duckdb]]
+:documentationPath: /database/databases/
+:language: en_US
+
+= DuckDB
+
+DuckDB is an in-process SQL OLAP database management system.
+
+As an in-process database, DuckDB is easy to configure: specify the path to
your DuckDB filename as the database name, e.g.
`<PATH_TO_YOUR_DUCKDB_FILE>/duckdb`.
+
+[cols="2*",options="header"]
+|===
+| Option | Info
+|Type | Relational
+|Driver |
https://search.maven.org/artifact/org.duckdb/duckdb_jdbc/0.7.0/jar[Driver Link]
+|Version Included | 0.7.0
+|Hop Dependencies | None
+|Documentation | https://duckdb.org/docs/api/java.html
+|JDBC Url | jdbc:duckdb: (in memory) or jdbc:duckdb:<FILE_PATH>
+|Driver folder | Hop Installation/plugins/databases/duckdb/lib
+|===
+
+
diff --git a/integration-tests/duckdb/dev-env-config.json
b/integration-tests/duckdb/dev-env-config.json
new file mode 100644
index 0000000000..9f86eef0f2
--- /dev/null
+++ b/integration-tests/duckdb/dev-env-config.json
@@ -0,0 +1,7 @@
+{
+ "variables" : [ {
+ "name" : "DUCKDB_DIR",
+ "value" : "/tmp/duckdb",
+ "description" : ""
+ } ]
+}
\ No newline at end of file
diff --git a/integration-tests/duckdb/duckdb-read.hpl
b/integration-tests/duckdb/duckdb-read.hpl
new file mode 100644
index 0000000000..ab1d735fd9
--- /dev/null
+++ b/integration-tests/duckdb/duckdb-read.hpl
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+ <info>
+ <name>duckdb-read</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <pipeline_version/>
+ <pipeline_type>Normal</pipeline_type>
+ <parameters>
+ </parameters>
+ <capture_transform_performance>N</capture_transform_performance>
+
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+ <created_user>-</created_user>
+ <created_date>2023/02/20 19:36:52.555</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2023/02/20 19:36:52.555</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ <hop>
+ <from>read book_data</from>
+ <to>get nb_rows</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>get nb_rows</from>
+ <to>100k rows?</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>100k rows?</from>
+ <to>Dummy (do nothing)</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>100k rows?</from>
+ <to>Abort</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <transform>
+ <name>100k rows?</name>
+ <type>FilterRows</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <compare>
+ <condition>
+ <conditions>
+</conditions>
+ <function>=</function>
+ <leftvalue>nb_rows</leftvalue>
+ <negated>N</negated>
+ <operator>-</operator>
+ <value>
+ <isnull>N</isnull>
+ <length>-1</length>
+ <mask>####0;-####0</mask>
+ <name>constant</name>
+ <precision>0</precision>
+ <text>100000</text>
+ <type>Integer</type>
+ </value>
+ </condition>
+ </compare>
+ <send_false_to>Abort</send_false_to>
+ <send_true_to>Dummy (do nothing)</send_true_to>
+ <attributes/>
+ <GUI>
+ <xloc>432</xloc>
+ <yloc>64</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>get nb_rows</name>
+ <type>GroupBy</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <add_linenr>N</add_linenr>
+ <all_rows>N</all_rows>
+ <directory>${java.io.tmpdir}</directory>
+ <fields>
+ <field>
+ <aggregate>nb_rows</aggregate>
+ <subject>title</subject>
+ <type>COUNT_ANY</type>
+ <valuefield/>
+ </field>
+ </fields>
+ <give_back_row>Y</give_back_row>
+ <group>
+</group>
+ <ignore_aggregate>N</ignore_aggregate>
+ <linenr_fieldname/>
+ <prefix>grp</prefix>
+ <attributes/>
+ <GUI>
+ <xloc>288</xloc>
+ <yloc>64</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>read book_data</name>
+ <type>TableInput</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <connection>duckdb</connection>
+ <execute_each_row>N</execute_each_row>
+ <limit>0</limit>
+ <sql>SELECT
+ author
+, publisher
+, genre
+, title
+FROM main.book_data
+order by publisher, title
+</sql>
+ <variables_active>N</variables_active>
+ <attributes/>
+ <GUI>
+ <xloc>96</xloc>
+ <yloc>64</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Dummy (do nothing)</name>
+ <type>Dummy</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ <GUI>
+ <xloc>608</xloc>
+ <yloc>64</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Abort</name>
+ <type>Abort</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <abort_option>ABORT_WITH_ERROR</abort_option>
+ <always_log_rows>Y</always_log_rows>
+ <message/>
+ <row_threshold>0</row_threshold>
+ <attributes/>
+ <GUI>
+ <xloc>432</xloc>
+ <yloc>160</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git a/integration-tests/duckdb/duckdb-write.hpl
b/integration-tests/duckdb/duckdb-write.hpl
new file mode 100644
index 0000000000..eb2aadf4ac
--- /dev/null
+++ b/integration-tests/duckdb/duckdb-write.hpl
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+ <info>
+ <name>duckdb-write</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <pipeline_version/>
+ <pipeline_type>Normal</pipeline_type>
+ <parameters>
+ </parameters>
+ <capture_transform_performance>N</capture_transform_performance>
+
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+ <created_user>-</created_user>
+ <created_date>2023/02/20 19:03:40.339</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2023/02/20 19:03:40.339</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ <hop>
+ <from>generate 100k rows</from>
+ <to>fake book data</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>fake book data</from>
+ <to>write book data</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <transform>
+ <name>fake book data</name>
+ <type>Fake</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <fields>
+ <field>
+ <name>author</name>
+ <topic>author</topic>
+ <type>Book</type>
+ </field>
+ <field>
+ <name>publisher</name>
+ <topic>publisher</topic>
+ <type>Book</type>
+ </field>
+ <field>
+ <name>genre</name>
+ <topic>genre</topic>
+ <type>Book</type>
+ </field>
+ <field>
+ <name>title</name>
+ <topic>title</topic>
+ <type>Book</type>
+ </field>
+ </fields>
+ <locale>en</locale>
+ <attributes/>
+ <GUI>
+ <xloc>320</xloc>
+ <yloc>80</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>generate 100k rows</name>
+ <type>RowGenerator</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <fields>
+</fields>
+ <interval_in_ms>5000</interval_in_ms>
+ <last_time_field>FiveSecondsAgo</last_time_field>
+ <limit>100000</limit>
+ <never_ending>N</never_ending>
+ <row_time_field>now</row_time_field>
+ <attributes/>
+ <GUI>
+ <xloc>144</xloc>
+ <yloc>80</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>write book data</name>
+ <type>TableOutput</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <commit>1000</commit>
+ <connection>duckdb</connection>
+ <fields>
+</fields>
+ <ignore_errors>N</ignore_errors>
+ <only_when_have_rows>Y</only_when_have_rows>
+ <partitioning_daily>N</partitioning_daily>
+ <partitioning_enabled>N</partitioning_enabled>
+ <partitioning_field/>
+ <partitioning_monthly>Y</partitioning_monthly>
+ <return_field/>
+ <return_keys>N</return_keys>
+ <schema>main</schema>
+ <specify_fields>N</specify_fields>
+ <table>book_data</table>
+ <tablename_field/>
+ <tablename_in_field>N</tablename_in_field>
+ <tablename_in_table>Y</tablename_in_table>
+ <truncate>Y</truncate>
+ <use_batch>N</use_batch>
+ <attributes/>
+ <GUI>
+ <xloc>480</xloc>
+ <yloc>80</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git a/integration-tests/duckdb/hop-config.json
b/integration-tests/duckdb/hop-config.json
new file mode 100644
index 0000000000..102ac981d5
--- /dev/null
+++ b/integration-tests/duckdb/hop-config.json
@@ -0,0 +1,290 @@
+{
+ "variables": [
+ {
+ "name": "HOP_LENIENT_STRING_TO_NUMBER_CONVERSION",
+ "value": "N",
+ "description": "System wide flag to allow lenient string to number
conversion for backward compatibility. If this setting is set to \"Y\", an
string starting with digits will be converted successfully into a number.
(example: 192.168.1.1 will be converted into 192 or 192.168 or 192168 depending
on the decimal and grouping symbol). The default (N) will be to throw an error
if non-numeric symbols are found in the string."
+ },
+ {
+ "name": "HOP_COMPATIBILITY_DB_IGNORE_TIMEZONE",
+ "value": "N",
+ "description": "System wide flag to ignore timezone while writing
date/timestamp value to the database."
+ },
+ {
+ "name": "HOP_LOG_SIZE_LIMIT",
+ "value": "0",
+ "description": "The log size limit for all pipelines and workflows that
don't have the \"log size limit\" property set in their respective properties."
+ },
+ {
+ "name": "HOP_EMPTY_STRING_DIFFERS_FROM_NULL",
+ "value": "N",
+ "description": "NULL vs Empty String. If this setting is set to Y, an
empty string and null are different. Otherwise they are not."
+ },
+ {
+ "name": "HOP_MAX_LOG_SIZE_IN_LINES",
+ "value": "0",
+ "description": "The maximum number of log lines that are kept internally
by Hop. Set to 0 to keep all rows (default)"
+ },
+ {
+ "name": "HOP_MAX_LOG_TIMEOUT_IN_MINUTES",
+ "value": "1440",
+ "description": "The maximum age (in minutes) of a log line while being
kept internally by Hop. Set to 0 to keep all rows indefinitely (default)"
+ },
+ {
+ "name": "HOP_MAX_WORKFLOW_TRACKER_SIZE",
+ "value": "5000",
+ "description": "The maximum number of workflow trackers kept in memory"
+ },
+ {
+ "name": "HOP_MAX_ACTIONS_LOGGED",
+ "value": "5000",
+ "description": "The maximum number of action results kept in memory for
logging purposes."
+ },
+ {
+ "name": "HOP_MAX_LOGGING_REGISTRY_SIZE",
+ "value": "10000",
+ "description": "The maximum number of logging registry entries kept in
memory for logging purposes."
+ },
+ {
+ "name": "HOP_LOG_TAB_REFRESH_DELAY",
+ "value": "1000",
+ "description": "The hop log tab refresh delay."
+ },
+ {
+ "name": "HOP_LOG_TAB_REFRESH_PERIOD",
+ "value": "1000",
+ "description": "The hop log tab refresh period."
+ },
+ {
+ "name": "HOP_PLUGIN_CLASSES",
+ "value": null,
+ "description": "A comma delimited list of classes to scan for plugin
annotations"
+ },
+ {
+ "name": "HOP_PLUGIN_PACKAGES",
+ "value": null,
+ "description": "A comma delimited list of packages to scan for plugin
annotations (warning: slow!!)"
+ },
+ {
+ "name": "HOP_TRANSFORM_PERFORMANCE_SNAPSHOT_LIMIT",
+ "value": "0",
+ "description": "The maximum number of transform performance snapshots to
keep in memory. Set to 0 to keep all snapshots indefinitely (default)"
+ },
+ {
+ "name": "HOP_ROWSET_GET_TIMEOUT",
+ "value": "50",
+ "description": "The name of the variable that optionally contains an
alternative rowset get timeout (in ms). This only makes a difference for
extremely short lived pipelines."
+ },
+ {
+ "name": "HOP_ROWSET_PUT_TIMEOUT",
+ "value": "50",
+ "description": "The name of the variable that optionally contains an
alternative rowset put timeout (in ms). This only makes a difference for
extremely short lived pipelines."
+ },
+ {
+ "name": "HOP_CORE_TRANSFORMS_FILE",
+ "value": null,
+ "description": "The name of the project variable that will contain the
alternative location of the hop-transforms.xml file. You can use this to
customize the list of available internal transforms outside of the codebase."
+ },
+ {
+ "name": "HOP_CORE_WORKFLOW_ACTIONS_FILE",
+ "value": null,
+ "description": "The name of the project variable that will contain the
alternative location of the hop-workflow-actions.xml file."
+ },
+ {
+ "name": "HOP_SERVER_OBJECT_TIMEOUT_MINUTES",
+ "value": "1440",
+ "description": "This project variable will set a time-out after which
waiting, completed or stopped pipelines and workflows will be automatically
cleaned up. The default value is 1440 (one day)."
+ },
+ {
+ "name": "HOP_PIPELINE_PAN_JVM_EXIT_CODE",
+ "value": null,
+ "description": "Set this variable to an integer that will be returned as
the Pan JVM exit code."
+ },
+ {
+ "name": "HOP_DISABLE_CONSOLE_LOGGING",
+ "value": "N",
+ "description": "Set this variable to Y to disable standard Hop logging
to the console. (stdout)"
+ },
+ {
+ "name": "HOP_REDIRECT_STDERR",
+ "value": "N",
+ "description": "Set this variable to Y to redirect stderr to Hop
logging."
+ },
+ {
+ "name": "HOP_REDIRECT_STDOUT",
+ "value": "N",
+ "description": "Set this variable to Y to redirect stdout to Hop
logging."
+ },
+ {
+ "name": "HOP_DEFAULT_NUMBER_FORMAT",
+ "value": null,
+ "description": "The name of the variable containing an alternative
default number format"
+ },
+ {
+ "name": "HOP_DEFAULT_BIGNUMBER_FORMAT",
+ "value": null,
+ "description": "The name of the variable containing an alternative
default bignumber format"
+ },
+ {
+ "name": "HOP_DEFAULT_INTEGER_FORMAT",
+ "value": null,
+ "description": "The name of the variable containing an alternative
default integer format"
+ },
+ {
+ "name": "HOP_DEFAULT_DATE_FORMAT",
+ "value": null,
+ "description": "The name of the variable containing an alternative
default date format"
+ },
+ {
+ "name": "HOP_DEFAULT_TIMESTAMP_FORMAT",
+ "value": null,
+ "description": "The name of the variable containing an alternative
default timestamp format"
+ },
+ {
+ "name": "HOP_DEFAULT_SERVLET_ENCODING",
+ "value": null,
+ "description": "Defines the default encoding for servlets, leave it
empty to use Java default encoding"
+ },
+ {
+ "name": "HOP_FAIL_ON_LOGGING_ERROR",
+ "value": "N",
+ "description": "Set this variable to Y when you want the
workflow/pipeline fail with an error when the related logging process (e.g. to
a database) fails."
+ },
+ {
+ "name": "HOP_AGGREGATION_MIN_NULL_IS_VALUED",
+ "value": "N",
+ "description": "Set this variable to Y to set the minimum to NULL if
NULL is within an aggregate. Otherwise by default NULL is ignored by the MIN
aggregate and MIN is set to the minimum value that is not NULL. See also the
variable HOP_AGGREGATION_ALL_NULLS_ARE_ZERO."
+ },
+ {
+ "name": "HOP_AGGREGATION_ALL_NULLS_ARE_ZERO",
+ "value": "N",
+ "description": "Set this variable to Y to return 0 when all values
within an aggregate are NULL. Otherwise by default a NULL is returned when all
values are NULL."
+ },
+ {
+ "name": "HOP_COMPATIBILITY_TEXT_FILE_OUTPUT_APPEND_NO_HEADER",
+ "value": "N",
+ "description": "Set this variable to Y for backward compatibility for
the Text File Output transform. Setting this to Ywill add no header row at all
when the append option is enabled, regardless if the file is existing or not."
+ },
+ {
+ "name": "HOP_PASSWORD_ENCODER_PLUGIN",
+ "value": "Hop",
+ "description": "Specifies the password encoder plugin to use by ID (Hop
is the default)."
+ },
+ {
+ "name": "HOP_SYSTEM_HOSTNAME",
+ "value": null,
+ "description": "You can use this variable to speed up hostname lookup.
Hostname lookup is performed by Hop so that it is capable of logging the server
on which a workflow or pipeline is executed."
+ },
+ {
+ "name": "HOP_SERVER_JETTY_ACCEPTORS",
+ "value": null,
+ "description": "A variable to configure jetty option: acceptors for
Carte"
+ },
+ {
+ "name": "HOP_SERVER_JETTY_ACCEPT_QUEUE_SIZE",
+ "value": null,
+ "description": "A variable to configure jetty option: acceptQueueSize
for Carte"
+ },
+ {
+ "name": "HOP_SERVER_JETTY_RES_MAX_IDLE_TIME",
+ "value": null,
+ "description": "A variable to configure jetty option:
lowResourcesMaxIdleTime for Carte"
+ },
+ {
+ "name":
"HOP_COMPATIBILITY_MERGE_ROWS_USE_REFERENCE_STREAM_WHEN_IDENTICAL",
+ "value": "N",
+ "description": "Set this variable to Y for backward compatibility for
the Merge Rows (diff) transform. Setting this to Y will use the data from the
reference stream (instead of the comparison stream) in case the compared rows
are identical."
+ },
+ {
+ "name": "HOP_SPLIT_FIELDS_REMOVE_ENCLOSURE",
+ "value": "false",
+ "description": "Set this variable to false to preserve enclosure symbol
after splitting the string in the Split fields transform. Changing it to true
will remove first and last enclosure symbol from the resulting string chunks."
+ },
+ {
+ "name": "HOP_ALLOW_EMPTY_FIELD_NAMES_AND_TYPES",
+ "value": "false",
+ "description": "Set this variable to TRUE to allow your pipeline to pass
'null' fields and/or empty types."
+ },
+ {
+ "name": "HOP_GLOBAL_LOG_VARIABLES_CLEAR_ON_EXPORT",
+ "value": "false",
+ "description": "Set this variable to false to preserve global log
variables defined in pipeline / workflow Properties -> Log panel. Changing it
to true will clear it when export pipeline / workflow."
+ },
+ {
+ "name": "HOP_FILE_OUTPUT_MAX_STREAM_COUNT",
+ "value": "1024",
+ "description": "This project variable is used by the Text File Output
transform. It defines the max number of simultaneously open files within the
transform. The transform will close/reopen files as necessary to insure the max
is not exceeded"
+ },
+ {
+ "name": "HOP_FILE_OUTPUT_MAX_STREAM_LIFE",
+ "value": "0",
+ "description": "This project variable is used by the Text File Output
transform. It defines the max number of milliseconds between flushes of files
opened by the transform."
+ },
+ {
+ "name": "HOP_USE_NATIVE_FILE_DIALOG",
+ "value": "N",
+ "description": "Set this value to Y if you want to use the system file
open/save dialog when browsing files"
+ },
+ {
+ "name": "HOP_AUTO_CREATE_CONFIG",
+ "value": "Y",
+ "description": "Set this value to N if you don't want to automatically
create a hop configuration file (hop-config.json) when it's missing"
+ }
+ ],
+ "LocaleDefault": "en_BE",
+ "guiProperties": {
+ "FontFixedSize": "13",
+ "MaxUndo": "100",
+ "DarkMode": "Y",
+ "FontNoteSize": "13",
+ "ShowOSLook": "Y",
+ "FontFixedStyle": "0",
+ "FontNoteName": ".AppleSystemUIFont",
+ "FontFixedName": "Monospaced",
+ "FontGraphStyle": "0",
+ "FontDefaultSize": "13",
+ "GraphColorR": "255",
+ "FontGraphSize": "13",
+ "IconSize": "32",
+ "BackgroundColorB": "255",
+ "FontNoteStyle": "0",
+ "FontGraphName": ".AppleSystemUIFont",
+ "FontDefaultName": ".AppleSystemUIFont",
+ "GraphColorG": "255",
+ "UseGlobalFileBookmarks": "Y",
+ "FontDefaultStyle": "0",
+ "GraphColorB": "255",
+ "BackgroundColorR": "255",
+ "BackgroundColorG": "255",
+ "WorkflowDialogStyle": "RESIZE,MAX,MIN",
+ "LineWidth": "1",
+ "ContextDialogShowCategories": "Y"
+ },
+ "projectsConfig": {
+ "enabled": true,
+ "projectMandatory": true,
+ "environmentMandatory": true,
+ "defaultProject": "default",
+ "defaultEnvironment": null,
+ "standardParentProject": "default",
+ "standardProjectsFolder": null,
+ "projectConfigurations": [
+ {
+ "projectName": "default",
+ "projectHome": "${HOP_CONFIG_FOLDER}",
+ "configFilename": "project-config.json"
+ }
+ ],
+ "lifecycleEnvironments": [
+ {
+ "name": "dev",
+ "purpose": "Testing",
+ "projectName": "default",
+ "configurationFiles": [
+ "${PROJECT_HOME}/dev-env-config.json"
+ ]
+ }
+ ],
+ "projectLifecycles": []
+ }
+}
\ No newline at end of file
diff --git a/integration-tests/duckdb/main-0001-read-write-duckdb.hwf
b/integration-tests/duckdb/main-0001-read-write-duckdb.hwf
new file mode 100644
index 0000000000..9a672bd6a6
--- /dev/null
+++ b/integration-tests/duckdb/main-0001-read-write-duckdb.hwf
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<workflow>
+ <name>main-0001-read-write-duckdb</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <workflow_version/>
+ <created_user>-</created_user>
+ <created_date>2023/02/20 20:24:40.087</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2023/02/20 20:24:40.087</modified_date>
+ <parameters>
+ </parameters>
+ <actions>
+ <action>
+ <name>Start</name>
+ <description/>
+ <type>SPECIAL</type>
+ <attributes/>
+ <DayOfMonth>1</DayOfMonth>
+ <hour>12</hour>
+ <intervalMinutes>60</intervalMinutes>
+ <intervalSeconds>0</intervalSeconds>
+ <minutes>0</minutes>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
+ <weekDay>1</weekDay>
+ <parallel>N</parallel>
+ <xloc>50</xloc>
+ <yloc>50</yloc>
+ <attributes_hac/>
+ </action>
+ <action>
+ <name>create book_data</name>
+ <description/>
+ <type>SQL</type>
+ <attributes/>
+ <sql>DROP TABLE IF EXISTS main.book_data;
+
+CREATE TABLE main.book_data
+(
+ author VARCHAR(150)
+, publisher VARCHAR(150)
+, genre VARCHAR(150)
+, title VARCHAR(150)
+)
+;</sql>
+ <useVariableSubstitution>F</useVariableSubstitution>
+ <sqlfromfile>F</sqlfromfile>
+ <sqlfilename/>
+ <sendOneStatement>F</sendOneStatement>
+ <connection>duckdb</connection>
+ <parallel>N</parallel>
+ <xloc>192</xloc>
+ <yloc>48</yloc>
+ <attributes_hac/>
+ </action>
+ <action>
+ <name>duckdb-write.hpl</name>
+ <description/>
+ <type>PIPELINE</type>
+ <attributes/>
+ <filename>${PROJECT_HOME}/duckdb-write.hpl</filename>
+ <params_from_previous>N</params_from_previous>
+ <exec_per_row>N</exec_per_row>
+ <clear_rows>N</clear_rows>
+ <clear_files>N</clear_files>
+ <set_logfile>N</set_logfile>
+ <logfile/>
+ <logext/>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <loglevel>Basic</loglevel>
+ <set_append_logfile>N</set_append_logfile>
+ <wait_until_finished>Y</wait_until_finished>
+ <create_parent_folder>N</create_parent_folder>
+ <run_configuration>local</run_configuration>
+ <parameters>
+ <pass_all_parameters>Y</pass_all_parameters>
+ </parameters>
+ <parallel>N</parallel>
+ <xloc>384</xloc>
+ <yloc>48</yloc>
+ <attributes_hac/>
+ </action>
+ <action>
+ <name>duckdb-read.hpl</name>
+ <description/>
+ <type>PIPELINE</type>
+ <attributes/>
+ <filename>${PROJECT_HOME}/duckdb-read.hpl</filename>
+ <params_from_previous>N</params_from_previous>
+ <exec_per_row>N</exec_per_row>
+ <clear_rows>N</clear_rows>
+ <clear_files>N</clear_files>
+ <set_logfile>N</set_logfile>
+ <logfile/>
+ <logext/>
+ <add_date>N</add_date>
+ <add_time>N</add_time>
+ <loglevel>Basic</loglevel>
+ <set_append_logfile>N</set_append_logfile>
+ <wait_until_finished>Y</wait_until_finished>
+ <create_parent_folder>N</create_parent_folder>
+ <run_configuration>local</run_configuration>
+ <parameters>
+ <pass_all_parameters>Y</pass_all_parameters>
+ </parameters>
+ <parallel>N</parallel>
+ <xloc>576</xloc>
+ <yloc>48</yloc>
+ <attributes_hac/>
+ </action>
+ </actions>
+ <hops>
+ <hop>
+ <from>Start</from>
+ <to>create book_data</to>
+ <enabled>Y</enabled>
+ <evaluation>Y</evaluation>
+ <unconditional>Y</unconditional>
+ </hop>
+ <hop>
+ <from>create book_data</from>
+ <to>duckdb-write.hpl</to>
+ <enabled>Y</enabled>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ </hop>
+ <hop>
+ <from>duckdb-write.hpl</from>
+ <to>duckdb-read.hpl</to>
+ <enabled>Y</enabled>
+ <evaluation>Y</evaluation>
+ <unconditional>N</unconditional>
+ </hop>
+ </hops>
+ <notepads>
+ </notepads>
+ <attributes/>
+</workflow>
diff --git
a/integration-tests/duckdb/metadata/pipeline-run-configuration/local.json
b/integration-tests/duckdb/metadata/pipeline-run-configuration/local.json
new file mode 100644
index 0000000000..11a9ee03d2
--- /dev/null
+++ b/integration-tests/duckdb/metadata/pipeline-run-configuration/local.json
@@ -0,0 +1,21 @@
+{
+ "engineRunConfiguration": {
+ "Local": {
+ "feedback_size": "50000",
+ "sample_size": "100",
+ "sample_type_in_gui": "Last",
+ "wait_time": "20",
+ "rowset_size": "10000",
+ "safe_mode": false,
+ "show_feedback": false,
+ "topo_sort": false,
+ "gather_metrics": false,
+ "transactional": false
+ }
+ },
+ "defaultSelection": true,
+ "configurationVariables": [],
+ "name": "local",
+ "description": "",
+ "executionInfoLocationName": "Runs your pipelines locally with the standard
local Hop pipeline engine"
+}
\ No newline at end of file
diff --git a/integration-tests/duckdb/metadata/rdbms/duckdb.json
b/integration-tests/duckdb/metadata/rdbms/duckdb.json
new file mode 100644
index 0000000000..8a24a97558
--- /dev/null
+++ b/integration-tests/duckdb/metadata/rdbms/duckdb.json
@@ -0,0 +1,26 @@
+{
+ "rdbms": {
+ "DuckDB": {
+ "databaseName": "${DUCKDB_DIR}",
+ "pluginId": "DuckDB",
+ "accessType": 0,
+ "hostname": "",
+ "password": "Encrypted ",
+ "pluginName": "DuckDB",
+ "port": "",
+ "attributes": {
+ "SUPPORTS_TIMESTAMP_DATA_TYPE": "N",
+ "QUOTE_ALL_FIELDS": "N",
+ "SUPPORTS_BOOLEAN_DATA_TYPE": "Y",
+ "FORCE_IDENTIFIERS_TO_LOWERCASE": "N",
+ "PRESERVE_RESERVED_WORD_CASE": "Y",
+ "SQL_CONNECT": "",
+ "FORCE_IDENTIFIERS_TO_UPPERCASE": "N",
+ "PREFERRED_SCHEMA_NAME": ""
+ },
+ "manualUrl": "",
+ "username": ""
+ }
+ },
+ "name": "duckdb"
+}
\ No newline at end of file
diff --git
a/integration-tests/duckdb/metadata/workflow-run-configuration/local.json
b/integration-tests/duckdb/metadata/workflow-run-configuration/local.json
new file mode 100644
index 0000000000..1d0cf74bae
--- /dev/null
+++ b/integration-tests/duckdb/metadata/workflow-run-configuration/local.json
@@ -0,0 +1,11 @@
+{
+ "engineRunConfiguration": {
+ "Local": {
+ "safe_mode": false,
+ "transactional": false
+ }
+ },
+ "defaultSelection": true,
+ "name": "local",
+ "description": "Runs your workflows locally with the standard local Hop
workflow engine"
+}
\ No newline at end of file
diff --git a/integration-tests/duckdb/project-config.json
b/integration-tests/duckdb/project-config.json
new file mode 100644
index 0000000000..6a91171e1c
--- /dev/null
+++ b/integration-tests/duckdb/project-config.json
@@ -0,0 +1,13 @@
+{
+ "metadataBaseFolder" : "${PROJECT_HOME}/metadata",
+ "unitTestsBasePath" : "${PROJECT_HOME}",
+ "dataSetsCsvFolder" : "${PROJECT_HOME}/datasets",
+ "enforcingExecutionInHome" : true,
+ "config" : {
+ "variables" : [ {
+ "name" : "HOP_LICENSE_HEADER_FILE",
+ "value" : "${PROJECT_HOME}/../asf-header.txt",
+ "description" : "This will automatically serialize the ASF license
header into pipelines and workflows in the integration test projects"
+ } ]
+ }
+}
\ No newline at end of file
diff --git a/plugins/databases/duckdb/pom.xml b/plugins/databases/duckdb/pom.xml
new file mode 100644
index 0000000000..db32643168
--- /dev/null
+++ b/plugins/databases/duckdb/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>hop-plugins-databases</artifactId>
+ <groupId>org.apache.hop</groupId>
+ <version>2.4.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>hop-databases-duckdb</artifactId>
+
+ <packaging>jar</packaging>
+
+ <name>Hop Plugins Databases DuckDB</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.duckdb</groupId>
+ <artifactId>duckdb_jdbc</artifactId>
+ <version>0.7.0</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git
a/plugins/databases/duckdb/src/main/java/org/apache/hop/databases/duckdb/DuckDBDatabaseMeta.java
b/plugins/databases/duckdb/src/main/java/org/apache/hop/databases/duckdb/DuckDBDatabaseMeta.java
new file mode 100644
index 0000000000..b14e889b03
--- /dev/null
+++
b/plugins/databases/duckdb/src/main/java/org/apache/hop/databases/duckdb/DuckDBDatabaseMeta.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.databases.duckdb;
+
+import org.apache.hop.core.Const;
+import org.apache.hop.core.database.BaseDatabaseMeta;
+import org.apache.hop.core.database.DatabaseMeta;
+import org.apache.hop.core.database.DatabaseMetaPlugin;
+import org.apache.hop.core.database.IDatabase;
+import org.apache.hop.core.exception.HopDatabaseException;
+import org.apache.hop.core.gui.plugin.GuiPlugin;
+import org.apache.hop.core.row.IValueMeta;
+
+@DatabaseMetaPlugin(
+ type="DuckDB",
+ typeDescription = "DuckDB",
+ documentationUrl = "/database/databases/apache-hive.html"
+)
+@GuiPlugin(id = "GUI-DuckDBDatabaseMeta")
+public class DuckDBDatabaseMeta extends BaseDatabaseMeta implements IDatabase {
+
+ private static final Class<?> PKG = DuckDBDatabaseMeta.class; // For
Translator
+
+ @Override
+ public String getFieldDefinition(IValueMeta v, String tk, String pk,
boolean useAutoIncrement, boolean addFieldName, boolean addCr) {
+ // https://duckdb.org/docs/sql/data_types/overview.html
+ String retval = "";
+
+ String fieldname = v.getName();
+ int length = v.getLength();
+ int precision = v.getPrecision();
+
+ if (addFieldName) {
+ retval += fieldname + " ";
+ }
+
+ int type = v.getType();
+ switch (type) {
+ case IValueMeta.TYPE_TIMESTAMP:
+ case IValueMeta.TYPE_DATE:
+ retval += "TIMESTAMP";
+ break;
+ case IValueMeta.TYPE_BOOLEAN:
+ if (isSupportsBooleanDataType()) {
+ retval += "BOOLEAN";
+ } else {
+ retval += "CHAR(1)";
+ }
+ break;
+ case IValueMeta.TYPE_NUMBER:
+ case IValueMeta.TYPE_INTEGER:
+ case IValueMeta.TYPE_BIGNUMBER:
+ if (fieldname.equalsIgnoreCase(tk)
+ || // Technical key
+ fieldname.equalsIgnoreCase(pk) // Primary key
+ ) {
+ retval += "IDENTITY";
+ } else {
+ if (length > 0) {
+ if (precision > 0 || length > 18) {
+ retval += "DECIMAL(" + length + ", " + precision +
")";
+ } else {
+ if (length > 9) {
+ retval += "BIGINT";
+ } else {
+ if (length < 5) {
+ if (length < 3) {
+ retval += "TINYINT";
+ } else {
+ retval += "SMALLINT";
+ }
+ } else {
+ retval += "INTEGER";
+ }
+ }
+ }
+
+ } else {
+ retval += "DOUBLE";
+ }
+ }
+ break;
+ case IValueMeta.TYPE_STRING:
+ if (length >= DatabaseMeta.CLOB_LENGTH) {
+ retval += "TEXT";
+ } else {
+ retval += "VARCHAR";
+ if (length > 0) {
+ retval += "(" + length;
+ } else {
+ retval += "(" + Integer.MAX_VALUE;
+ }
+ retval += ")";
+ }
+ break;
+ case IValueMeta.TYPE_BINARY:
+ retval += "BLOB";
+ break;
+ default:
+ retval += "UNKNOWN";
+ break;
+ }
+
+ if (addCr) {
+ retval += Const.CR;
+ }
+
+ return retval;
+ }
+
+ @Override
+ public int[] getAccessTypeList() {
+ return new int[] {DatabaseMeta.TYPE_ACCESS_NATIVE};
+ }
+
+ @Override
+ public String getDriverClass() {
+ return "org.duckdb.DuckDBDriver";
+ }
+
+ @Override
+ public String getURL(String hostname, String port, String databaseName)
throws HopDatabaseException {
+ return "jdbc:duckdb:" + databaseName;
+ }
+
+ @Override
+ public String getAddColumnStatement(String tableName, IValueMeta v, String
tk, boolean useAutoIncrement, String pk, boolean semicolon) {
+ return "ALTER TABLE "
+ + tableName
+ + " ADD COLUMN "
+ + getFieldDefinition(v, tk, pk, useAutoIncrement,true, false);
+ }
+
+ @Override
+ public String getModifyColumnStatement(String tableName, IValueMeta v,
String tk, boolean useAutoIncrement, String pk, boolean semicolon) {
+ return "ALTER TABLE "
+ + tableName
+ + " ALTER COLUMN "
+ + getFieldDefinition(v, tk, pk, useAutoIncrement,true, false);
+ }
+
+ @Override
+ public boolean isSupportsBooleanDataType() {
+ return true;
+ }
+
+}
diff --git a/plugins/databases/pom.xml b/plugins/databases/pom.xml
index 568e746d9c..09855743a7 100644
--- a/plugins/databases/pom.xml
+++ b/plugins/databases/pom.xml
@@ -104,6 +104,7 @@
<module>clickhouse</module>
<module>cockroachdb</module>
<module>hive</module>
+ <module>duckdb</module>
</modules>
</profile>