Skip to content
This repository was archived by the owner on Sep 1, 2025. It is now read-only.

Commit 2e55040

Browse files
authored
Merge pull request #15 from mat02/develop
Fix compatibility with FB2.x
2 parents 6550955 + 33734ce commit 2e55040

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

src/metabase/driver/firebird.clj

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,24 @@
44
[string :as str]]
55
[clojure.java.jdbc :as jdbc]
66
[honeysql.core :as hsql]
7+
[honeysql.format :as hformat]
78
[java-time :as t]
89
[metabase.driver :as driver]
910
[metabase.driver.common :as driver.common]
11+
;; [metabase.driver.sql-jdbc.sync.describe-database :as sql-jdbc.sync.describe-database]
1012
[metabase.driver.sql-jdbc
1113
[common :as sql-jdbc.common]
1214
[connection :as sql-jdbc.conn]
1315
[sync :as sql-jdbc.sync]]
16+
[metabase.driver.sql-jdbc.sync.common :as sql-jdbc.sync.common]
1417
[metabase.driver.sql.query-processor :as sql.qp]
1518
[metabase.util
16-
[honeysql-extensions :as hx]
17-
[ssh :as ssh]])
19+
[honeysql-extensions :as hx]]
20+
[metabase.util.ssh :as ssh])
1821
(:import [java.sql DatabaseMetaData Time]
19-
[java.time LocalDate LocalDateTime LocalTime OffsetDateTime OffsetTime ZonedDateTime]))
22+
[java.time LocalDate LocalDateTime LocalTime OffsetDateTime OffsetTime ZonedDateTime]
23+
[java.sql Connection DatabaseMetaData ResultSet]))
24+
2025

2126
(driver/register! :firebird, :parent :sql-jdbc)
2227

@@ -42,7 +47,7 @@
4247
(sql-jdbc.common/handle-additional-options details)))
4348

4449
(defmethod driver/can-connect? :firebird [driver details]
45-
(let [connection (sql-jdbc.conn/connection-details->spec driver (ssh/include-ssh-tunnel details))]
50+
(let [connection (sql-jdbc.conn/connection-details->spec driver (ssh/include-ssh-tunnel! details))]
4651
(= 1 (first (vals (first (jdbc/query connection ["SELECT 1 FROM RDB$DATABASE"])))))))
4752

4853
;; Use pattern matching because some parameters can have a length parameter, e.g. VARCHAR(255)
@@ -80,6 +85,37 @@
8085
items
8186
(* items (dec page)))]))
8287

88+
89+
;; When selecting constants Firebird doesn't check privileges, we have to select all fields
90+
(defn simple-select-probe-query
91+
[driver schema table]
92+
{:pre [(string? table)]}
93+
(let [honeysql {:select [:*]
94+
:from [(sql.qp/->honeysql driver (hx/identifier :table schema table))]
95+
:where [:not= 1 1]}
96+
honeysql (sql.qp/apply-top-level-clause driver :limit honeysql {:limit 0})]
97+
(sql.qp/format-honeysql driver honeysql)))
98+
99+
(defn- execute-select-probe-query
100+
[driver ^Connection conn [sql & params]]
101+
{:pre [(string? sql)]}
102+
(with-open [stmt (sql-jdbc.sync.common/prepare-statement driver conn sql params)]
103+
;; attempting to execute the SQL statement will throw an Exception if we don't have permissions; otherwise it will
104+
;; truthy wheter or not it returns a ResultSet, but we can ignore that since we have enough info to proceed at
105+
;; this point.
106+
(.execute stmt)))
107+
108+
(defmethod sql-jdbc.sync/have-select-privilege? :sql-jdbc
109+
[driver conn table-schema table-name]
110+
;; Query completes = we have SELECT privileges
111+
;; Query throws some sort of no permissions exception = no SELECT privileges
112+
(let [sql-args (simple-select-probe-query driver table-schema table-name)]
113+
(try
114+
(execute-select-probe-query driver conn sql-args)
115+
true
116+
(catch Throwable _
117+
false))))
118+
83119
(defmethod sql-jdbc.sync/active-tables :firebird [& args]
84120
(apply sql-jdbc.sync/post-filtered-active-tables args))
85121

@@ -153,6 +189,23 @@
153189
(defmethod sql.qp/date [:firebird :quarter-of-year] [_ _ expr] (hx/+ (hx// (hx/- (hsql/call :extract :MONTH expr) 1) 3) 1))
154190
(defmethod sql.qp/date [:firebird :year] [_ _ expr] (hsql/call :extract :YEAR expr))
155191

192+
;; Firebird 2.x doesn't support TRUE/FALSE, replacing them with 1 and 0
193+
(defmethod sql.qp/->honeysql [:firebird Boolean] [_ bool] (if bool 1 0))
194+
195+
;; Firebird 2.x doesn't support SUBSTRING arugments seperated by commas, but uses FROM and FOR keywords
196+
(defmethod sql.qp/->honeysql [:firebird :substring]
197+
[driver [_ arg start length]]
198+
(let [col-name (hformat/to-sql (sql.qp/->honeysql driver arg))]
199+
(if length
200+
(reify
201+
hformat/ToSql
202+
(to-sql [_]
203+
(str "substring(" col-name " FROM " start " FOR " length ")")))
204+
(reify
205+
hformat/ToSql
206+
(to-sql [_]
207+
(str "substring(" col-name " FROM " start ")"))))))
208+
156209
(defmethod sql.qp/add-interval-honeysql-form :firebird [driver hsql-form amount unit]
157210
(if (= unit :quarter)
158211
(recur driver hsql-form (hx/* amount 3) :month)

0 commit comments

Comments
 (0)