Source

Clj-DBSpec /

Filename Size Date modified Message
src
623 B
6.2 KB
3.3 KB
-*- markdown -*-

# Clj-DBSpec v0.1

Clj-DBSpec is a common configuration spec for dealing with relational databases
e.g. data source, connection, conversion of schema/tables/columns/indices names
between the database and Clojure.


## Usage

Maven/Leiningen dependency details are here: [http://clojars.org/org.bituf/clj-dbspec](http://clojars.org/org.bituf/clj-dbspec)

Examples for usage can be found in the tutorial below:


## Building/Installation

You will need Maven 2 to build from sources. Execute the following:

    $ mvn clean package  # packages up a JAR in "target" dir
    $ mvn install        # to install to your local Maven repo
    $ mvn clojure:gendoc # generate Clojure API documentation


## License

Copyright (C) 2011 Shantanu Kumar (kumar.shantanu at gmail dot com)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this software except in compliance with the License.
   You may obtain a copy of the License at

   [http://www.apache.org/licenses/LICENSE-2.0](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.


# Documentation

Clj-DBSpec can be used after including the following in your
namespace:

    (ns example.app
      (:require [org.bituf.clj-dbspec :as spec]))

Feel free to browse the documentation and source code/unit tests for details.


## Quickstart

### Dynamic var for database configuration keys

    spec/*dbspec*

This var is bound to a map containing well known keys and corresponding values.
Those keys are:

    :datasource  (javax.sql.DataSource, default: nil)
                  1. When you rebind this var with :datasource you SHOULD also
                     include a cached :dbmetadata value.
                  2. Everytime a connection is taken from the datasource you
                     SHOULD re-bind this var to include the :connection object.
    :connection  (java.sql.Connection, default: nil)
                  1. If the connection is not taken from a datasource you SHOULD
                     include a cached :dbmetadata value while re-binding.
    :dbmetadata  (map, default: empty map)
                  1. This is usually result of dbmeta function.
    :catalog     (Clojure form - String, Keyword etc.; default nil)
                  1. Catalog name - SHOULD be converted using db-iden
    :schema      (Clojure form - String, Keyword etc.; default nil)
                  1. Schema name - SHOULD be converted using db-iden
    :show-sql    (Booleanl default true)
                  1. If true, SQL statements should be printed.
    :clj-to-db   (function, default: to string, replace '-' => '_')
                  1. Dictates how are identifiers converted from Clojure to
                     the Database.
                  2. The default value is the least common denominator that
                     works with most databases. Override as necessary.
    :db-to-clj   (function, default: to lower-case keyword, replace '_' => '-')
                  1. Dictates how are identifiers are converted from the
                     Database to Clojure.
                  2. The default value is the least common denominator that
                     works with most databases. Override as necessary.

  Libraries MAY expose their own API to re-bind this var to new values - they
  MUST NOT alter the type/semantics of the well-defined keys. They MAY
  introduce custom keys with unique prefixes e.g. :com.foo.xlib.conn-pool-name
  (in order to prevent name collision), which may be useful to interoperate
  with other libraries.

The idiomatic use of this var is to write middleware to alter the values of
certain keys. Some pre-built middleware are:

    wrap-dbspec
    wrap-datasource
    wrap-datasource-conn
    wrap-connection


### Create raw database connection

**Important: You must include the JDBC drivers on the classpath on your own.**

    ;; without username/password
    (spec/make-connection
      ;; driver-classname - for H2 database
      "org.h2.Driver"
      ;; JDBC URL - for in-memory H2 database
      "jdbc:h2:mem:db1")

    ;; with username/password
    (spec/make-connection
      ;; driver-classname - for H2 database
      "org.h2.Driver"
      ;; JDBC URL - for in-memory H2 database
      "jdbc:h2:mem:db1"
      ;; username
      "sa"
      ;; password
      "")


### Work with a DataSource

    ;; assuming we are using Clj-DBCP for creating data source
    (let [ds (dbcp/h2-memory-datasource)
          g  (spec/wrap-datasource ds
               #(with-open [conn (.getConnection (:datasource spec/*dbspec*))]
                  (-> (.createStatement conn)
                    (.executeQuery "SELECT 1;"))))]
      (g))


### Work with a Connection obtained from a DataSource

    ;; assuming we are using Clj-DBCP for creating data source
    (let [ds (dbcp/h2-memory-datasource)
          g  (spec/wrap-datasource-conn ds
               #(-> (.createStatement (:connection spec/*dbspec*))
                  (.executeQuery "SELECT 1;")))]
      (g))


### Convert Clojure name to database name (name of table/column/column-type etc.)

Let us see the default behavior:

    (spec/db-iden :Emp-Name) ; returns "emp_name"

You can modify the behavior as follows:

    (let [g (wrap-dbspec {:clj-to-db  (fn [iden]
                                        (if (string? iden) iden
                                          (apply str (replace {\- "xx"}
                                                       (name iden)))))}
              ;; returns "EMPxxNAME"
              #(spec/db-iden :Emp-Name))]
      (g))


### Convert database name to Clojure name (name of table/column/column-type etc.)

Let us see the default behavior:

    (spec/clj-iden "Emp_Name") ; returns :emp-name

You can modify the behavior by reassigning a convertor function to the key
:db-to-clj (as shown in Clojure-to-database name example above.)


## Reference

Please check The Bitumen Framework Handbook [https://bitbucket.org/kumarshantanu/bituf-handbook/src](https://bitbucket.org/kumarshantanu/bituf-handbook/src)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.