taylorlapeyre / Oj

Licence: epl-1.0
🍹 A Clojure library for talking to your database.

Programming Languages

clojure
4091 projects

Labels

Projects that are alternatives of or similar to Oj

Linq2db
Linq to database provider.
Stars: ✭ 2,211 (+1192.98%)
Mutual labels:  sql, orm
Impatient
Ain't nobody got time for data
Stars: ✭ 110 (-35.67%)
Mutual labels:  sql, orm
F3 Cortex
A multi-engine ORM / ODM for the PHP Fat-Free Framework
Stars: ✭ 101 (-40.94%)
Mutual labels:  sql, orm
Oxidizer
📦 A Rust ORM based on tokio-postgres and refinery
Stars: ✭ 100 (-41.52%)
Mutual labels:  sql, orm
Sequelize Ui
Browser-based GUI for previewing and generating Sequelize project files.
Stars: ✭ 142 (-16.96%)
Mutual labels:  sql, orm
Fastsql
Database rapid development framework for Java(数据库快速开发框架).
Stars: ✭ 100 (-41.52%)
Mutual labels:  sql, orm
Sqlobject
SQLObject, an object-relational mapper for Python
Stars: ✭ 106 (-38.01%)
Mutual labels:  sql, orm
Sql
A delightful SQL ORM ☺️
Stars: ✭ 89 (-47.95%)
Mutual labels:  sql, orm
Firenze
Adapter based JavaScript ORM for Node.js and the browser
Stars: ✭ 131 (-23.39%)
Mutual labels:  sql, orm
Sworm
a write-only ORM for Node.js
Stars: ✭ 128 (-25.15%)
Mutual labels:  sql, orm
Elasticsearch
Use SQL statements to query elasticsearch
Stars: ✭ 98 (-42.69%)
Mutual labels:  sql, orm
Sqlservice
The missing SQLAlchemy ORM interface.
Stars: ✭ 159 (-7.02%)
Mutual labels:  sql, orm
Nymph
Data objects for JavaScript and PHP.
Stars: ✭ 97 (-43.27%)
Mutual labels:  sql, orm
Phero
这个是一个独立的orm组件可以使用在任何系统中,提供灵活的orm操作,注解形式的数据库和类的映射。This is a database query tool library. swoole mysql pool.
Stars: ✭ 100 (-41.52%)
Mutual labels:  sql, orm
Jplusone
Tool for automatic detection and asserting "N+1 SELECT problem" occurences in JPA based Spring Boot Java applications and finding origin of JPA issued SQL statements in general
Stars: ✭ 91 (-46.78%)
Mutual labels:  sql, orm
Xorm
xorm是一个简单而强大的Go语言ORM库,通过它可以使数据库操作非常简便。本库是基于原版xorm的定制增强版本,为xorm提供类似ibatis的配置文件及动态SQL支持,支持AcitveRecord操作
Stars: ✭ 1,394 (+715.2%)
Mutual labels:  sql, orm
Evolutility Server Node
Model-driven REST or GraphQL backend for CRUD and more, written in Javascript, using Node.js, Express, and PostgreSQL.
Stars: ✭ 84 (-50.88%)
Mutual labels:  sql, orm
Sequelize
Sequelize module for Nest framework (node.js) 🍈
Stars: ✭ 88 (-48.54%)
Mutual labels:  sql, orm
Npdynamodb
A Node.js Simple Query Builder and ORM for AWS DynamoDB
Stars: ✭ 113 (-33.92%)
Mutual labels:  sql, orm
Norm
Access a database in one line of code.
Stars: ✭ 152 (-11.11%)
Mutual labels:  sql, orm

oj

oj

Build Status

A refreshing Clojure library for talking to your database, heavily influenced by Ring.

Features

  • Gives you a standard interface for running and generating SQL
  • Focuses on the most common and useful features of SQL
  • Enforces type checking and validation for queries
  • Sensible defaults
  • Concise and powerful API
  • Encourages reusable components

Anti-features

  • Doesn't try to implement the entiretly of SQL
  • Doesn't require you to write SQL
  • Doesn't create its own domain-specific language
  • Doesn't surprise you

The SPEC file provides a complete description of the OJ interface.

Installation

Add this to your Leiningen :dependencies:

[oj "0.3.0"]

You'll also need a database driver (thanks to yesql for providing this handy table):

Database :dependencies Entry
PostgreSQL [org.postgresql/postgresql "9.3-1102-jdbc41"]
MySQL [mysql/mysql-connector-java "5.1.32"]
Oracle [com.oracle/ojdbc14 "10.2.0.4.0"]
SQLite [org.xerial/sqlite-jdbc "3.7.2"]
Derby [org.apache.derby/derby "10.11.1.1"]

Usage

Queries are represented as a Clojure map. The full specification of a query map can be found here.

(def users-named-taylor
  {:table :users
   :select [:id :email]
   :where {:first_name "taylor"}})

Queries can be executed by passing a query map and a database config into oj/exec:

(def db {:subprotocol "mysql"
         :subname "//127.0.0.1:3306/wishwheel3"
         :user "root"
         :password ""})

(oj/exec users-named-taylor db)
; => ({:id 1 :email "[email protected]"} ...)

Modifiers are functions that transform a query map into another query map. This allows us to chain them together. Some basic modifiers are provided by default at oj.modifiers.

(require [oj.core :as oj]
         [oj.modifiers :as db])

(defn find-by-username [username]
  (-> (db/query :users)
      (db/select [:id :username :email :created_at])
      (db/where {:username username})
      (oj/exec db-config)
      (first)))

(find-by-username "taylorlapeyre")
; => {:id 1 :username "taylorlapeyre"}

OJ's roots in regular Clojure data structures make it extremely powerful for building abstractions.

(defn user [& forms]
  (let [query (reduce merge {:table :users} forms)]
    (oj/exec query db)))

(user {:where {:id 1}})
=> SELECT * FROM users WHERE users.id=1

(user {:where {:id 1}}
      {:select [:id :username]})
=> SELECT id, username FROM users WHERE users.id=1

Not quite ActiveRecord, but it's getting there. And in 3 lines of code no less!

Of course, you can also perform all of the standard CRUD operations that you'd expect:

(defn create [user-data]
  (when (valid? user-data)
    (-> (db/query :users)
        (db/insert user-data)
        (oj/exec db-config))))

(defn update [id user-data]
  (when (valid? user-data)
    (-> (db/query :users)
        (db/where {:id id})
        (db/update user-data)
        (oj/exec db-config))))

(defn delete [id]
  (-> (db/query :users)
      (db/where {:id id})
      (db/delete)
      (oj/exec db-config)))

How about using SQL's aggregate functions? OJ allows you to use those as well, using a Clojure-like syntax.

For example, to get the average price of all items:

(-> (db/query :items)
    (select '(avg :price))
    (oj/exec db-config))
; => 46.76

For more advanced uses, OJ will provide the data in a useful format.

(-> (db/query :items)
    (group :published)
    (select [:published '(avg :price)])
    (oj/exec db-config))
; ({:published 1 :avg {:price 64.35}}, {:published 0 :avg {:price 10.35}})

OJ gives you a lot of flexibility. For instance, you could write some custom modifier functions and then execute them when you like. This allows you to combine them.

(defn find-by-username
[query username]
(-> query
    (db/where {:username username})))

(-> (query :users)
  (find-by-username "taylor")
  (oj/exec db-config)
  (first))

Printing SQL Queries

If you'd like SQL queries logged to your console when executed, you can enable it by setting the environment variable PRINT_DB_LOGS to true.

Contributing

  1. Fork this repository
  2. Create a new branch
  3. Do your thing
  4. Submit a pull request with a description of the change.

TODO

  • Joins

License

Copyright © 2014 Taylor Lapeyre

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].