Skip to content
Snippets Groups Projects
Unverified Commit 7438a4d1 authored by Cam Saul's avatar Cam Saul
Browse files

Support Oracle CLOB data types [ci oracle]

parent 87047968
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,8 @@
[metabase.driver.sql.query-processor :as sql.qp]
[metabase.util
[honeysql-extensions :as hx]
[ssh :as ssh]]))
[ssh :as ssh]])
(:import [java.sql ResultSet Types]))
(driver/register! :oracle, :parent :sql-jdbc)
......@@ -322,3 +323,7 @@
(defmethod sql-jdbc.execute/set-timezone-sql :oracle [_]
"ALTER session SET time_zone = %s")
;; instead of returning a CLOB object, return the String. (#9026)
(defmethod sql-jdbc.execute/read-column [:oracle Types/CLOB] [_ _, ^ResultSet resultset, _, ^Integer i]
(.getString resultset i))
(ns metabase.driver.oracle-test
"Tests for specific behavior of the Oracle driver."
(:require [expectations :refer :all]
[metabase.driver :as driver]
(:require [clojure.java.jdbc :as jdbc]
[expectations :refer :all]
[metabase
[driver :as driver]
[query-processor :as qp]
[query-processor-test :as qp.test]
[util :as u]]
[metabase.driver.sql-jdbc.connection :as sql-jdbc.conn]
[metabase.test.data.datasets :refer [expect-with-driver]]
[metabase.test.util :as tu]
[metabase.test.util.log :as tu.log]))
[metabase.models
[field :refer [Field]]
[table :refer [Table]]]
[metabase.test
[data :as data]
[util :as tu]]
[metabase.test.data
[datasets :refer [expect-with-driver]]
[oracle :as oracle.tx]
[sql :as sql.tx]]
[metabase.test.util.log :as tu.log]
[toucan.util.test :as tt]))
;; make sure we can connect with an SID
(expect
......@@ -73,3 +87,40 @@
(expect-with-driver :oracle
"UTC"
(tu/db-timezone-id))
(defn- do-with-temp-user [f]
(let [username (tu/random-name)]
(try
(oracle.tx/create-user! username)
(f username)
(finally
(oracle.tx/drop-user! username)))))
(defmacro ^:private with-temp-user
"Run `body` with a temporary user bound, binding their name to `username-binding`. Use this to create the equivalent
of temporary one-off databases."
[[username-binding] & body]
`(do-with-temp-user (fn [~username-binding] ~@body)))
;; Make sure Oracle CLOBs are returned as text (#9026)
(expect-with-driver :oracle
[[1M "Hello"]
[2M nil]]
(let [details (:details (data/db))
spec (sql-jdbc.conn/connection-details->spec :oracle details)
execute! (fn [format-string & args]
(jdbc/execute! spec (apply format format-string args)))
pk-type (sql.tx/pk-sql-type :oracle)]
(with-temp-user [username]
(execute! "CREATE TABLE \"%s\".\"messages\" (\"id\" %s, \"message\" CLOB)" username pk-type)
(execute! "INSERT INTO \"%s\".\"messages\" (\"id\", \"message\") VALUES (1, 'Hello')" username)
(execute! "INSERT INTO \"%s\".\"messages\" (\"id\", \"message\") VALUES (2, NULL)" username)
(tt/with-temp* [Table [table {:schema username, :name "messages", :db_id (data/id)}]
Field [_ {:table_id (u/get-id table), :name "id", :base_type "type/Integer"}]
Field [_ {:table_id (u/get-id table), :name "message", :base_type "type/Text"}]]
(qp.test/rows
(qp/process-query
{:database (data/id)
:type :query
:query {:source-table (u/get-id table)}}))))))
......@@ -25,6 +25,7 @@
(defonce ^:private session-schema-number (rand-int 200))
(defonce ^:private session-schema (str "CAM_" session-schema-number))
(defonce ^:private session-password (apply str (repeatedly 16 #(rand-nth (map char (range (int \a) (inc (int \z))))))))
;; Session password is only used when creating session user, not anywhere else
(def ^:private connection-details
(delay
......@@ -111,11 +112,22 @@
:when (re-find #"^CAM_" schema)]
(execute! "DROP USER %s CASCADE" schema)))
(defmethod tx/before-run :oracle [_]
(defn create-user!
;; default to using session-password for all users created this session
([username]
(create-user! username session-password))
([username password]
(execute! "CREATE USER %s IDENTIFIED BY %s DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS"
username
password)))
(defn drop-user! [username]
(u/ignore-exceptions
(execute! "DROP USER %s CASCADE" session-schema))
(execute! "CREATE USER %s IDENTIFIED BY %s DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS"
session-schema session-password))
(execute! "DROP USER %s CASCADE" username)))
(defmethod tx/before-run :oracle [_]
(drop-user! session-schema)
(create-user! session-schema))
(defmethod tx/after-run :oracle [_]
(execute! "DROP USER %s CASCADE" session-schema))
(drop-user! session-schema))
......@@ -12,7 +12,6 @@
(metabot.cmd/command "list")))
;; `metabot/list` shouldn't show archived Cards (#9283)
;; NOCOMMIT
(expect
#"1 most recent cards"
(tt/with-temp* [Card [_]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment