Liking cljdoc? Tell your friends :D

metabase.driver

Metabase Drivers handle various things we need to do with connected data warehouse databases, including things like introspecting their schemas and processing and running MBQL queries. Drivers must implement some or all of the multimethods defined below, and register themselves with a call to regsiter!.

SQL-based drivers can use the :sql driver as a parent, and JDBC-based SQL drivers can use :sql-jdbc. Both of these drivers define additional multimethods that child drivers should implement; see metabase.driver.sql and metabase.driver.sql-jdbc for more details.

Metabase Drivers handle various things we need to do with connected data warehouse databases, including things like
introspecting their schemas and processing and running MBQL queries. Drivers must implement some or all of the
multimethods defined below, and register themselves with a call to `regsiter!`.

SQL-based drivers can use the `:sql` driver as a parent, and JDBC-based SQL drivers can use `:sql-jdbc`. Both of
these drivers define additional multimethods that child drivers should implement; see `metabase.driver.sql` and
`metabase.driver.sql-jdbc` for more details.
raw docstring

*driver*clj

Current driver (a keyword such as :postgres) in use by the Query Processor/tests/etc. Bind this with with-driver below. The QP binds the driver this way in the bind-driver middleware.

Current driver (a keyword such as `:postgres`) in use by the Query Processor/tests/etc. Bind this with `with-driver`
below. The QP binds the driver this way in the `bind-driver` middleware.
sourceraw docstring

abstract?clj

(abstract? driver)

Is driver an abstract "base class"?

Is `driver` an abstract "base class"?
sourceraw docstring

add-parent!clj

(add-parent! driver new-parent)

Add a new parent to driver.

Add a new parent to `driver`.
sourceraw docstring

available?cljmultimethoddeprecated

(available? driver)

Is this driver available for use? (i.e. should we show it as an option when adding a new database?) This is true by default for all non-abstract driver types and false for abstract ones; some drivers might want to override this to return false even if the driver isn't abstract -- for example, the Oracle driver might return false if the JDBC driver it depends on is not available.

This method is also used in tests to determine whether the standard set of Query Processor tests should automatically against it; for one-off test drivers to test specific functionality, you should return false.

DEPRECATED -- drivers that require external dependencies are now shipping as plugins; they can declare dependencies on external classes, and we can skip loading them entirely if the dependencies are not available. Please do not implement this method; it will most likely be removed before version 1.0 ships.

Is this driver available for use? (i.e. should we show it as an option when adding a new database?) This is `true` by
default for all non-abstract driver types and false for abstract ones; some drivers might want to override this to
return false even if the driver isn't abstract -- for example, the Oracle driver might return false if the JDBC
driver it depends on is not available.

This method is also used in tests to determine whether the standard set of Query Processor tests should
automatically against it; for one-off test drivers to test specific functionality, you should return `false`.

DEPRECATED -- drivers that require external dependencies are now shipping as plugins; they can declare dependencies
on external classes, and we can skip loading them entirely if the dependencies are not available. Please do not
implement this method; it will most likely be removed before version 1.0 ships.
sourceraw docstring

can-connect?cljmultimethod

(can-connect? driver details)

Check whether we can connect to a Database with DETAILS-MAP and perform a simple query. For example, a SQL database might try running a query like SELECT 1;. This function should return true or false.

Check whether we can connect to a `Database` with DETAILS-MAP and perform a simple query. For example, a SQL
database might try running a query like `SELECT 1;`. This function should return `true` or `false`.
sourceraw docstring

connection-propertiescljmultimethod

(connection-properties driver)

Return information about the connection properties that should be exposed to the user for databases that will use this driver. This information is used to build the UI for editing a Database details map, and for validating it on the backend. It should include things like host, port, and other driver-specific parameters. Each property must conform to the ConnectionDetailsProperty schema above.

There are several definitions for common properties available in the metabase.driver.common namespace, such as default-host-details and default-port-details. Prefer using these if possible.

Like display-name, lazy-loaded drivers should specify this in their plugin manifest; lazy-loaded-driver will automatically create an implementation for you.

Return information about the connection properties that should be exposed to the user for databases that will use
this driver. This information is used to build the UI for editing a Database `details` map, and for validating it on
the backend. It should include things like `host`, `port`, and other driver-specific parameters. Each property must
conform to the `ConnectionDetailsProperty` schema above.

There are several definitions for common properties available in the `metabase.driver.common` namespace, such as
`default-host-details` and `default-port-details`. Prefer using these if possible.

Like `display-name`, lazy-loaded drivers should specify this in their plugin manifest; `lazy-loaded-driver` will
automatically create an implementation for you.
sourceraw docstring

ConnectionDetailsPropertyclj

Schema for a map containing information about a connection property we should ask the user to supply when setting up a new database, as returned by an implementation of connection-properties.

Schema for a map containing information about a connection property we should ask the user to supply when setting up
a new database, as returned by an implementation of `connection-properties`.
sourceraw docstring

current-db-timecljmultimethod

(current-db-time driver database)

Return the current time and timezone from the perspective of database. You can use metabase.driver.common/current-db-time to implement this. This should return a Joda-Time DateTime.

Return the current time and timezone from the perspective of `database`. You can use
`metabase.driver.common/current-db-time` to implement this. This should return a Joda-Time `DateTime`.
sourceraw docstring

date-intervalcljmultimethod

(date-interval driver unit amount)

Return an driver-appropriate representation of a moment relative to the current moment in time. By default, this returns an Timestamp by calling metabase.util.date/relative-date; but when possible drivers should return a native form so we can be sure the correct timezone is applied. For example, SQL drivers should return a HoneySQL form to call the appropriate SQL fns:

(date-interval :postgres :month 1) -> (hsql/call :+ :%now (hsql/raw "INTERVAL '1 month'"))

Return an driver-appropriate representation of a moment relative to the current moment in time. By default, this
returns an `Timestamp` by calling `metabase.util.date/relative-date`; but when possible drivers should return a
native form so we can be sure the correct timezone is applied. For example, SQL drivers should return a HoneySQL
form to call the appropriate SQL fns:

  (date-interval :postgres :month 1) -> (hsql/call :+ :%now (hsql/raw "INTERVAL '1 month'"))
sourceraw docstring

describe-databasecljmultimethod

(describe-database driver database)

Return a map containing information that describes all of the tables in a database, an instance of the Database model. It is expected that this function will be peformant and avoid draining meaningful resources of the database. Results should match the metabase.sync.interface/DatabaseMetadata schema.

Return a map containing information that describes all of the tables in a `database`, an instance of the `Database`
model. It is expected that this function will be peformant and avoid draining meaningful resources of the database.
Results should match the `metabase.sync.interface/DatabaseMetadata` schema.
sourceraw docstring

describe-tablecljmultimethod

(describe-table driver database table)

Return a map containing information that describes the physical schema of table (i.e. the fields contained therein). database will be an instance of the Database model; and table, an instance of the Table model. It is expected that this function will be peformant and avoid draining meaningful resources of the database. Results should match the metabase.sync.interface/TableMetadata schema.

Return a map containing information that describes the physical schema of `table` (i.e. the fields contained
therein). `database` will be an instance of the `Database` model; and `table`, an instance of the `Table` model. It is
expected that this function will be peformant and avoid draining meaningful resources of the database. Results
should match the `metabase.sync.interface/TableMetadata` schema.
sourceraw docstring

describe-table-fkscljmultimethod

(describe-table-fks this database table)

Return information about the foreign keys in a table. Required for drivers that support :foreign-keys. Results should match the metabase.sync.interface/FKMetadata schema.

Return information about the foreign keys in a `table`. Required for drivers that support `:foreign-keys`. Results
should match the `metabase.sync.interface/FKMetadata` schema.
sourceraw docstring

dispatch-on-initialized-driverclj

(dispatch-on-initialized-driver driver & _)

Like dispatch-on-uninitialized-driver, but guarantees a driver is initialized before dispatch. Prefer the-driver for trivial methods that should do not require the driver to be initialized (e.g., ones that simply return information about the driver, but do not actually connect to any databases.)

Like `dispatch-on-uninitialized-driver`, but guarantees a driver is initialized before dispatch. Prefer `the-driver`
for trivial methods that should do not require the driver to be initialized (e.g., ones that simply return
information about the driver, but do not actually connect to any databases.)
sourceraw docstring

display-namecljmultimethod

(display-name driver)

A nice name for the driver that we'll display to in the admin panel, e.g. "PostgreSQL" for :postgres. Default implementation capitializes the name of the driver, e.g. :presto becomes "Presto".

When writing a driver that you plan to ship as a separate, lazy-loading plugin (including core drivers packaged this way, like SQLite), you do not need to implement this method; instead, specifiy it in your plugin manifest, and lazy-loaded-driver will create an implementation for you. Probably best if we only have one place where we set values for this.

A nice name for the driver that we'll display to in the admin panel, e.g. "PostgreSQL" for `:postgres`. Default
implementation capitializes the name of the driver, e.g. `:presto` becomes "Presto".

When writing a driver that you plan to ship as a separate, lazy-loading plugin (including core drivers packaged this
way, like SQLite), you do not need to implement this method; instead, specifiy it in your plugin manifest, and
`lazy-loaded-driver` will create an implementation for you. Probably best if we only have one place where we set
values for this.
sourceraw docstring

driver-featuresclj

Set of all features a driver can support.

Set of all features a driver can support.
sourceraw docstring

execute-querycljmultimethod

(execute-query driver query)

Execute a native query against the database and return the results.

The query passed in will conform to the schema in metabase.mbql.schema/Query. MBQL queries are transformed to native queries via the mbql->native QP middleware, which in turn calls this driver's implementation of mbql->native before reaching this method.

Results should look like:

{:columns ["id", "name"] :rows [[1 "Lucky Bird"] [2 "Rasta Can"]]}

Execute a *native* query against the database and return the results.

The query passed in will conform to the schema in `metabase.mbql.schema/Query`. MBQL queries are transformed to
native queries via the `mbql->native` QP middleware, which in turn calls this driver's implementation of
`mbql->native` before reaching this method.

Results should look like:

  {:columns ["id", "name"]
   :rows    [[1 "Lucky Bird"]
             [2 "Rasta Can"]]}
sourceraw docstring

format-custom-field-namecljmultimethod

(format-custom-field-name driver custom-field-name)

Return the custom name passed via an MBQL :named clause so it matches the way it is returned in the results. This is used by the post-processing annotation stage to find the correct metadata to include with fields in the results. The default implementation is identity, meaning the resulting field will have exactly the same name as passed to the :named clause. Certain drivers like Redshift always lowercase these names, so this method is provided for those situations.

Return the custom name passed via an MBQL `:named` clause so it matches the way it is returned in the results. This
is used by the post-processing annotation stage to find the correct metadata to include with fields in the results.
The default implementation is `identity`, meaning the resulting field will have exactly the same name as passed to
the `:named` clause. Certain drivers like Redshift always lowercase these names, so this method is provided for
those situations.
sourceraw docstring

hierarchyclj

Driver hierarchy. Used by driver multimethods for dispatch. Add new drivers with regsiter!.

Driver hierarchy. Used by driver multimethods for dispatch. Add new drivers with `regsiter!`.
sourceraw docstring

humanize-connection-error-messagecljmultimethod

(humanize-connection-error-message this message)

Return a humanized (user-facing) version of an connection error message string. Generic error messages are provided in metabase.driver.common/connection-error-messages; return one of these whenever possible.

Return a humanized (user-facing) version of an connection error message string. Generic error messages are provided
in `metabase.driver.common/connection-error-messages`; return one of these whenever possible.
sourceraw docstring

initialize!cljmultimethod

(initialize! driver)

DO NOT CALL THIS METHOD DIRECTLY. Called automatically once and only once the first time a non-trivial driver method is called; implementers should do one-time initialization as needed (for example, registering JDBC drivers used internally by the driver.)

'Trivial' methods include a tiny handful of ones like connection-properties that simply provide information about the driver, but do not connect to databases; these can be be supplied, for example, by a Metabase plugin manifest file (which is supplied for lazy-loaded drivers). Methods that require connecting to a database dispatch off of the-initialized-driver, which will initialize a driver if not already done so.

You will rarely need to write an implentation for this method yourself. A lazy-loaded driver (like most of the Metabase drivers in v1.0 and above) are automatiaclly given an implentation of this method that performs the init-steps specified in the plugin manifest (such as loading namespaces in question).

If you do need to implement this method yourself, you do not need to call parent implementations. We'll take care of that for you.

DO NOT CALL THIS METHOD DIRECTLY. Called automatically once and only once the first time a non-trivial driver method
is called; implementers should do one-time initialization as needed (for example, registering JDBC drivers used
internally by the driver.)

'Trivial' methods include a tiny handful of ones like `connection-properties` that simply provide information about
the driver, but do not connect to databases; these can be be supplied, for example, by a Metabase plugin manifest
file (which is supplied for lazy-loaded drivers). Methods that require connecting to a database dispatch off of
`the-initialized-driver`, which will initialize a driver if not already done so.

You will rarely need to write an implentation for this method yourself. A lazy-loaded driver (like most of the
Metabase drivers in v1.0 and above) are automatiaclly given an implentation of this method that performs the
`init-steps` specified in the plugin manifest (such as loading namespaces in question).

If you do need to implement this method yourself, you do not need to call parent implementations. We'll take care of
that for you.
sourceraw docstring

initialized?clj

(initialized? driver)

Has driver been initialized? (See initialize! below for a discussion of what exactly this means.)

Has `driver` been initialized? (See `initialize!` below for a discussion of what exactly this means.)
sourceraw docstring

mbql->nativecljmultimethod

(mbql->native driver query)

Transpile an MBQL query into the appropriate native query form. query will match the schema for an MBQL query in metabase.mbql.schema/Query; this function should return a native query that conforms to that schema.

If the underlying query language supports remarks or comments, the driver should use query->remark to generate an appropriate message and include that in an appropriate place; alternatively a driver might directly include the query's :info dictionary if the underlying language is JSON-based.

The result of this function will be passed directly into calls to execute-query.

For example, a driver like Postgres would build a valid SQL expression and return a map such as:

{:query "-- Metabase card: 10 user: 5 SELECT * FROM my_table"}

Transpile an MBQL query into the appropriate native query form. `query` will match the schema for an MBQL query in
`metabase.mbql.schema/Query`; this function should return a native query that conforms to that schema.

If the underlying query language supports remarks or comments, the driver should use `query->remark` to generate an
appropriate message and include that in an appropriate place; alternatively a driver might directly include the
query's `:info` dictionary if the underlying language is JSON-based.

The result of this function will be passed directly into calls to `execute-query`.

For example, a driver like Postgres would build a valid SQL expression and return a map such as:

  {:query "-- Metabase card: 10 user: 5
            SELECT * FROM my_table"}
sourceraw docstring

notify-database-updatedcljmultimethod

(notify-database-updated driver database)

Notify the driver that the attributes of a database have changed, or that `database was deleted. This is specifically relevant in the event that the driver was doing some caching or connection pooling; the driver should release ALL related resources when this is called.

Notify the driver that the attributes of a `database` have changed, or that `database was deleted. This is
specifically relevant in the event that the driver was doing some caching or connection pooling; the driver should
release ALL related resources when this is called.
sourceraw docstring

process-query-in-contextcljmultimethod

(process-query-in-context driver qp)

Similar to sync-in-context, but for running queries rather than syncing. This should be used to do things like open DB connections that need to remain open for the duration of post-processing. This function follows a middleware pattern and is injected into the QP middleware stack immediately after the Query Expander; in other words, it will receive the expanded query. See the Mongo and H2 drivers for examples of how this is intended to be used.

 (defn process-query-in-context [driver qp]
   (fn [query]
     (qp query)))
Similar to `sync-in-context`, but for running queries rather than syncing. This should be used to do things like
open DB connections that need to remain open for the duration of post-processing. This function follows a middleware
pattern and is injected into the QP middleware stack immediately after the Query Expander; in other words, it will
receive the expanded query. See the Mongo and H2 drivers for examples of how this is intended to be used.

     (defn process-query-in-context [driver qp]
       (fn [query]
         (qp query)))
sourceraw docstring

register!clj

(register! driver & {:keys [parent abstract?]})

Register a driver.

(register! :sql, :abstract? true)

(register! :postgres, :parent :sql-jdbc)

Valid options are:

:parent (default = none)

Parent driver(s) to derive from. Drivers inherit method implementations from their parents similar to the way inheritance works in OOP. Specify multiple direct parents by passing a collection of parents.

You can add additional parents to a driver using add-parent! below; this is how test extensions are implemented.

:abstract? (default = false)

Is this an abstract driver (i.e. should we hide it in the admin interface, and disallow running queries with it)?

Note that because concreteness is implemented as part of our keyword hierarchy it is not currently possible to create an abstract driver with a concrete driver as its parent, since it would still ultimately derive from ::concrete.

Register a driver.

  (register! :sql, :abstract? true)

  (register! :postgres, :parent :sql-jdbc)

Valid options are:

###### `:parent` (default = none)

Parent driver(s) to derive from. Drivers inherit method implementations from their parents similar to the way
inheritance works in OOP. Specify multiple direct parents by passing a collection of parents.

You can add additional parents to a driver using `add-parent!` below; this is how test extensions are implemented.

###### `:abstract?` (default = false)

Is this an abstract driver (i.e. should we hide it in the admin interface, and disallow running queries with it)?

Note that because concreteness is implemented as part of our keyword hierarchy it is not currently possible to
create an abstract driver with a concrete driver as its parent, since it would still ultimately derive from
`::concrete`.
sourceraw docstring

registered?clj

(registered? driver)

Is driver a valid registered driver?

Is `driver` a valid registered driver?
sourceraw docstring

report-timezoneclj

(report-timezone)
(report-timezone new-value)

Connection timezone to use when executing queries. Defaults to system timezone.

report-timezone is a string Setting. You can get its value by calling:

(report-timezone)

and set its value by calling:

(report-timezone <new-value>)

You can also set its value with the env var MB_REPORT_TIMEZONE.

Clear its value by calling:

(report-timezone nil)

Its default value is nil.

Connection timezone to use when executing queries. Defaults to system timezone.

`report-timezone` is a string Setting. You can get its value by calling:

    (report-timezone)

and set its value by calling:

    (report-timezone <new-value>)

You can also set its value with the env var `MB_REPORT_TIMEZONE`.

Clear its value by calling:

    (report-timezone nil)

Its default value is `nil`.
sourceraw docstring

splice-parameters-into-native-querycljmultimethod

(splice-parameters-into-native-query driver query)

For a native query that has separate parameters, such as a JDBC prepared statement, e.g.

{:query "SELECT * FROM birds WHERE name = ?", :params ["Reggae"]}

splice the parameters in to the native query as literals so it can be executed by the user, e.g.

{:query "SELECT * FROM birds WHERE name = 'Reggae'"}

This is used to power features such as 'Convert this Question to SQL' in the Query Builder. Normally when executing the query we'd like to leave the statement as a prepared one and pass parameters that way instead of splicing them in as literals so as to avoid SQL injection vulnerabilities. Thus the results of this method are not normally executed by the Query Processor when processing an MBQL query. However when people convert a question to SQL they can see what they will be executing and edit the query as needed.

Input to this function follows the same shape as output of mbql->native -- that is, it will be a so-called 'inner' native query, with :query and :params keys, as in the example code above; output should be of the same format. This method might be called even if no splicing needs to take place, e.g. if :params is empty; implementations should be sure to handle this situation correctly.

For databases that do not feature concepts like 'prepared statements', this method need not be implemented; the default implementation is an identity function.

For a native query that has separate parameters, such as a JDBC prepared statement, e.g.

  {:query "SELECT * FROM birds WHERE name = ?", :params ["Reggae"]}

splice the parameters in to the native query as literals so it can be executed by the user, e.g.

  {:query "SELECT * FROM birds WHERE name = 'Reggae'"}

This is used to power features such as 'Convert this Question to SQL' in the Query Builder. Normally when executing
the query we'd like to leave the statement as a prepared one and pass parameters that way instead of splicing them
in as literals so as to avoid SQL injection vulnerabilities. Thus the results of this method are not normally
executed by the Query Processor when processing an MBQL query. However when people convert a
question to SQL they can see what they will be executing and edit the query as needed.

Input to this function follows the same shape as output of `mbql->native` -- that is, it will be a so-called 'inner'
native query, with `:query` and `:params` keys, as in the example code above; output should be of the same format.
This method might be called even if no splicing needs to take place, e.g. if `:params` is empty; implementations
should be sure to handle this situation correctly.

For databases that do not feature concepts like 'prepared statements', this method need not be implemented; the
default implementation is an identity function.
sourceraw docstring

supports?cljmultimethod

(supports? driver feature)

Does this driver support a certain feature? (A feature is a keyword, and can be any of the ones listed above in driver-features.)

(supports? :postgres :set-timezone) ; -> true

Does this driver support a certain `feature`? (A feature is a keyword, and can be any of the ones listed above in
`driver-features`.)

  (supports? :postgres :set-timezone) ; -> true
sourceraw docstring

sync-in-contextcljmultimethod

(sync-in-context driver database f)

Drivers may provide this function if they need to do special setup before a sync operation such as sync-database!. The sync operation itself is encapsulated as the lambda f, which must be called with no arguments.

(defn sync-in-context [driver database f] (with-connection [_ database] (f)))

Drivers may provide this function if they need to do special setup before a sync operation such as
`sync-database!`. The sync operation itself is encapsulated as the lambda `f`, which must be called with no arguments.

  (defn sync-in-context [driver database f]
    (with-connection [_ database]
      (f)))
sourceraw docstring

table-rows-seqcljmultimethod

(table-rows-seq driver database table)

Return a sequence of all the rows in a given TABLE, which is guaranteed to have at least :name and :schema keys. (It is guaranteed to satisfy the DatabaseMetadataTable schema in metabase.sync.interface.) Currently, this is only used for iterating over the values in a _metabase_metadata table. As such, the results are not expected to be returned lazily. There is no expectation that the results be returned in any given order.

This method is currently only used by the H2 driver to load the Sample Dataset, so it is not neccesary for any other drivers to implement it at this time.

Return a sequence of *all* the rows in a given TABLE, which is guaranteed to have at least `:name` and `:schema`
keys. (It is guaranteed to satisfy the `DatabaseMetadataTable` schema in `metabase.sync.interface`.) Currently, this
is only used for iterating over the values in a `_metabase_metadata` table. As such, the results are not expected to
be returned lazily. There is no expectation that the results be returned in any given order.

This method is currently only used by the H2 driver to load the Sample Dataset, so it is not neccesary for any other
drivers to implement it at this time.
sourceraw docstring

the-driverclj

(the-driver driver)

Inputs: [driver :- (s/cond-pre s/Str s/Keyword)]

Like Clojure core the-ns. Converts argument to a keyword, then loads and registers the driver if not already done, throwing an Exception if it fails or is invalid. Returns keyword.

This is useful in several cases:

;; Ensuring a driver is loaded & registered (isa? driver/hierarchy (the-driver :postgres) (the-driver :sql-jdbc)

;; Accepting either strings or keywords (e.g., in API endpoints) (the-driver "h2") ; -> :h2

;; Ensuring a driver you are passed is valid (db/insert! Database :engine (name (the-driver driver)))

(the-driver :postgres) ; -> :postgres (the-driver :baby) ; -> Exception

Inputs: [driver :- (s/cond-pre s/Str s/Keyword)]

Like Clojure core `the-ns`. Converts argument to a keyword, then loads and registers the driver if not already done,
throwing an Exception if it fails or is invalid. Returns keyword.

This is useful in several cases:

  ;; Ensuring a driver is loaded & registered
  (isa? driver/hierarchy (the-driver :postgres) (the-driver :sql-jdbc)

  ;; Accepting either strings or keywords (e.g., in API endpoints)
  (the-driver "h2") ; -> :h2

  ;; Ensuring a driver you are passed is valid
  (db/insert! Database :engine (name (the-driver driver)))

  (the-driver :postgres) ; -> :postgres
  (the-driver :baby)     ; -> Exception
sourceraw docstring

the-initialized-driverclj

(the-initialized-driver driver)

Like the-driver, but also initializes the driver if not already initialized.

Like `the-driver`, but also initializes the driver if not already initialized.
sourceraw docstring

with-drivercljmacro

(with-driver driver & body)

Bind current driver to driver and execute body.

(driver/with-driver :postgres ...)

Bind current driver to `driver` and execute `body`.

(driver/with-driver :postgres
  ...)
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close