diff --git a/.github/workflows/integration-tests-v2.yml b/.github/workflows/integration-tests-v2.yml index e1ff0ff..3d3bf40 100644 --- a/.github/workflows/integration-tests-v2.yml +++ b/.github/workflows/integration-tests-v2.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 with: repository: metabase/metabase - ref: "v0.48.0" + ref: "v0.52.4" - name: Checkout firebolt connector code uses: actions/checkout@v2 @@ -28,7 +28,7 @@ jobs: uses: actions/setup-java@v2 with: distribution: 'zulu' - java-version: '17' + java-version: '21' - name: Install clojure tools uses: DeLaGuardo/setup-clojure@3.7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b667d5..88ed205 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ on: description: 'Metabase version' required: false type: string - default: 'v0.48.0' + default: 'v0.52.4' jobs: publish: @@ -29,7 +29,7 @@ jobs: - name: "Install dependencies" env: - METABASE_VERSION: ${{ github.event.inputs.metabase-version || 'v0.48.0' }} + METABASE_VERSION: ${{ github.event.inputs.metabase-version || 'v0.52.4' }} run: | lein get-metabase-core lein deps diff --git a/README.md b/README.md index 2328185..fd2b191 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,35 @@ # Metabase Firebolt Driver +[Firebolt documentation page](https://docs.firebolt.io/Guides/integrations/metabase.html) + +## Overview + + ## Installation -Please follow Firebolt's [documentation](https://docs.firebolt.io/integrations/business-intelligence/connecting-to-metabase.html) to install the Metabase Firebolt driver on your Metabase instance. If you are using Metabase Cloud, no installation is required since the driver comes preinstalled. +### Get the driver +Download the latest driver jar from the [releases page](https://github.com/firebolt-db/metabase-firebolt-driver/releases). Make sure to check the [compatibility matrix](#compatibility-matrix) to get the right version. +**or** +Build the driver from source as described in the [Build from source](#build-from-source) section. + +### Run Metabase locally +1. Download the `metabase.jar` file from [Metabase download page](https://www.metabase.com/start/oss/jar). +2. Run Metabase first time. It will generate all the required files and directories, including the `/plugins` directory. +```shell + java -jar metabase.jar + ``` +3. Stop Metabase. +4. Copy the Firebolt driver jar to the Metabase `/plugins` directory +5. Start Metabase again. Firebolt connection should be available in the list of databases now. -## Configuring -1. Once you've started up Metabase, open http://localhost:3000 , go to add a database and select "Firebolt". -2. You'll need to provide the Database Name, Username and Password. +## Build from source ### Prerequisites - [Leiningen](https://leiningen.org/) -### Build from source +### Steps 1. Clone and build metabase dependency jar. @@ -49,23 +65,12 @@ Please follow Firebolt's [documentation](https://docs.firebolt.io/integrations/b LEIN_SNAPSHOTS_IN_RELEASE=true DEBUG=1 lein uberjar ``` -5. Let's assume we download `metabase.jar` from the [Metabase jar](https://www.metabase.com/docs/latest/operations-guide/running-the-metabase-jar-file.html) to `~/metabase/` and we built the project above. Copy the built jar to the Metabase plugins directly and run Metabase from there! - - ```shell - cd ~/metabase/ - java -jar metabase.jar - ``` - -You should see a message on startup similar to: - -``` -2019-05-07 23:27:32 INFO plugins.lazy-loaded-driver :: Registering lazy loading driver :firebolt... -2019-05-07 23:27:32 INFO metabase.driver :: Registered driver :firebolt (parents: #{:sql-jdbc}) 🚚 -``` +5. The jar will be available in the `target` directory. ## Compatibility matrix -| Metabase Release | Driver Version | -|------------------|----------------| -| <=0.47.x | 3.0.1 | -| \>=0.48.x | 3.1.0 | +| Metabase Release | Driver Version | Firebolt Version | +|------------------|----------------|------------------| +| <=0.47.x | 3.0.1 | 1.0 | +| \>=0.48.x | 3.1.0 | 1.0 and 2.0 | +| >=0.52 | 3.2.0 | 2.0 | diff --git a/project.clj b/project.clj index dd078d1..2602f11 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(def version "3.1.0") +(def version "3.2.0") (def uberjar-name (str "firebolt.metabase-driver-" version ".jar")) (def uberjar-file (str "target/uberjar/" uberjar-name)) @@ -40,12 +40,12 @@ "TMP_DIR=\\$(mktemp -d) && \\ wget -nv https://downloads.metabase.com/\\$METABASE_VERSION/metabase.jar -O \\$TMP_DIR/metabase.jar && \\ mkdir -p repo && \\ - mvn deploy:deploy-file -Durl=file:repo -DgroupId=com.firebolt -DartifactId=metabase-core -Dversion=1.40 -Dpackaging=jar -Dfile=\\$TMP_DIR/metabase.jar"]] + mvn deploy:deploy-file -Durl=file:repo -DgroupId=com.firebolt -DartifactId=metabase-core -Dversion=1.50 -Dpackaging=jar -Dfile=\\$TMP_DIR/metabase.jar"]] } :profiles {:provided - {:dependencies [[com.firebolt/metabase-core "1.40"]]} + {:dependencies [[com.firebolt/metabase-core "1.50"]]} :uberjar {:auto-clean true diff --git a/src/metabase/driver/firebolt.clj b/src/metabase/driver/firebolt.clj index 06de033..9fbc4f5 100644 --- a/src/metabase/driver/firebolt.clj +++ b/src/metabase/driver/firebolt.clj @@ -5,14 +5,12 @@ [clojure.java.jdbc :as jdbc] [java-time.api :as t] [metabase.driver :as driver] - [metabase.driver.common :as driver.common] [metabase.driver.sql-jdbc.sync.describe-table :as sql-jdbc.describe-table] [metabase.driver.sql-jdbc [common :as sql-jdbc.common] [connection :as sql-jdbc.conn] [sync :as sql-jdbc.sync]] [metabase.driver.sql-jdbc.execute.legacy-impl :as legacy] - [metabase.driver.sql.util.unprepare :as unprepare] [metabase.driver.sql.query-processor :as sql.qp] [metabase.driver.sql-jdbc.execute :as sql-jdbc.execute] [metabase.util @@ -177,22 +175,22 @@ (defmethod sql.qp/add-interval-honeysql-form :firebolt [_ dt amount unit] [[:date_add (name unit) (int amount) dt]]) ; Format a temporal value `t` as a SQL-style literal string, converting time datatype to SQL-style literal string -(defmethod unprepare/unprepare-value [:firebolt LocalTime] +(defmethod sql.qp/inline-value [:firebolt LocalTime] [_ t] (format "timestamp '%s'" (t/sql-timestamp t))) ; Converting ZonedDateTime datatype to SQL-style literal string -(defmethod unprepare/unprepare-value [:firebolt ZonedDateTime] +(defmethod sql.qp/inline-value [:firebolt ZonedDateTime] [_ t] (format "timestamptz '%s'" (u.date/format-sql (t/offset-date-time t)))) ; Converting OffsetDateTime datatype to SQL-style literal string -(defmethod unprepare/unprepare-value [:firebolt OffsetDateTime] +(defmethod sql.qp/inline-value [:firebolt OffsetDateTime] [_ t] (format "timestamptz '%s'" (u.date/format-sql (t/offset-date-time t)))) ; Converting OffsetTime datatype to SQL-style literal string -(defmethod unprepare/unprepare-value [:firebolt OffsetTime] +(defmethod sql.qp/inline-value [:firebolt OffsetTime] [_ t] (format "timestamptz '%s'" (u.date/format-sql (t/offset-date-time t)))) @@ -293,17 +291,24 @@ ) ;-------------------------Supported features--------------------------- -(doseq [[feature supported?] {:basic-aggregations true - :expression-aggregations true - :foreign-keys false - :binning false - :regex true - :standard-deviation-aggregations false - :nested-queries false - :case-sensitivity-string-filter-options false - :set-timezone true - :nested-fields false - :advanced-math-expressions false - :percentile-aggregations false - :schemas false}] -(defmethod driver/database-supports? [:firebolt feature] [_driver _feature _db] supported?)) +(doseq [[feature supported?] {:basic-aggregations true + :expression-aggregations true + :binning false + :regex true + :standard-deviation-aggregations false + :nested-queries false + :case-sensitivity-string-filter-options false + :set-timezone true + :nested-fields false + :advanced-math-expressions false + :percentile-aggregations false + :schemas false + :uploads false + :index-info false ;TODO: Implement index-info + :table-privileges false ;TODO: Implement table-privileges + :describe-fields false ;TODO: Implement describe-fields + :metadata/key-constraints false ; If foreign keys are enforced. + :identifiers-with-spaces true + :describe-indexes false ;TODO: Implement describe-indexes + }] + (defmethod driver/database-supports? [:firebolt feature] [_driver _feature _db] supported?)) diff --git a/test/metabase/driver/firebolt_test.clj b/test/metabase/driver/firebolt_test.clj index fb553f9..5a46212 100644 --- a/test/metabase/driver/firebolt_test.clj +++ b/test/metabase/driver/firebolt_test.clj @@ -15,7 +15,6 @@ [metabase.test.data.interface :as tx] [metabase.test.data.dataset-definitions :as dataset-defs] [clojure.string :as str] - [metabase.driver.sql.util.unprepare :as unprepare] [metabase [models :refer [Table, Database]] [sync :as sync] @@ -23,7 +22,6 @@ [metabase.driver.sql-jdbc.execute :as sql-jdbc.execute] [clojure.java.jdbc :as jdbc] [toucan2.core :as t2] - [honeysql.core :as hsql] ) (:import [java.sql Array ResultSet ResultSetMetaData Types Timestamp] [java.time LocalTime ZonedDateTime])) @@ -132,14 +130,14 @@ (sql.qp/date :firebolt :day-of-month "2021-06-06 12:12:12"))) (is (= [[:extract [:raw "doy" " FROM " [:cast "2021-06-06 12:12:12" :timestamptz]]]] (sql.qp/date :firebolt :day-of-year "2021-06-06 12:12:12"))) - (is (= (hsql/call :ceil - (hsql/call :/ + (is (= [:ceil + [:/ [[:extract [:raw "doy" " FROM " [:cast [[:date_add "day" -1 [[:date_trunc [:metabase.util.honey-sql-2/literal "week"] [:cast [[:date_add "day" 1 "2021-06-06 12:12:12"]] :timestamptz]]]]] :timestamptz]]]] - 7.0)) + 7.0]] (sql.qp/date :firebolt :week-of-year "2021-06-06 12:12:12"))) (is (= [[:extract [:raw "month" " FROM " [:cast "2021-06-06 12:12:12" :timestamptz]]]] (sql.qp/date :firebolt :month-of-year "2021-06-06 12:12:12"))) @@ -155,12 +153,12 @@ ; (is (= "SELECT CAST(CAST(NOW() AS TIMESTAMP) AS VARCHAR(24))" ; (driver.common/current-db-time-native-query :firebolt)))) -(deftest unprepare-values-test +(deftest inline-values-test (is (= "class java.time.LocalTime" - (unprepare/unprepare-value :firebolt LocalTime))) + (sql.qp/inline-value :firebolt LocalTime))) (is (= "class java.time.ZonedDateTime" - (unprepare/unprepare-value :firebolt ZonedDateTime)))) + (sql.qp/inline-value :firebolt ZonedDateTime)))) (deftest driver-support-test (is (= false diff --git a/test/metabase/test/data/firebolt.clj b/test/metabase/test/data/firebolt.clj index af5a22d..3709758 100644 --- a/test/metabase/test/data/firebolt.clj +++ b/test/metabase/test/data/firebolt.clj @@ -101,8 +101,8 @@ (defmethod sql.tx/add-fk-sql :firebolt [& _] nil) ; loads data by adding ids -(defmethod load-data/load-data! :firebolt [& args] - (apply load-data/load-data-add-ids! args)) +(defmethod load-data/row-xform :firebolt [& args] + (apply load-data/add-ids-xform args)) ; Modified the table name to be in the format of db_name_table_name. ; So get the table and view names to make all test cases to use this format while forming the query to run tests