PG docs, part 1
TL;DR: I’m writing a Postgres driver in pure Clojure. In general, works! Now I proceed with the most miserable part of the project: writing documentation. I decided to do it step by step and share it on my blog.
ToC
About
This project is a set of libraries related to the PostgreSQL
database. The primary library called pg-client
is a driver for Postgres
written in pure Clojure. By purity I mean, neither JDBC nor any other
third-party Java libraries are involved. Everything is driven by a TCP socket
and implementation of the Posrgres Wire protocol. Fun!
Besides the client, the project provides such various additions as a connection
pool (see pg-pool
). The pg-types
library holds the encoding and decoding
logic which determines how to write and read Clojure data from and into the
database. You can use this library separately in pair with JDBC.next and COPY
for efficient data transcoding in binary format.
The question you would probably ask is, why would create a Postgres client from
scratch? JDBC has been around for decades, and there are also good
clojure.java.jdbc
and jdbc.next
wrappers on top of it?
The answer is: that although these two libraries are amazing, they don’t disclose all Postgres features. JDBC is an abstraction whose main goal is to satisfy all the DB engines. A general library that works with MS SQL, MySQL, and Postgres at the same time would reduce the variety of features each backend is capable of.
Postgres is a great database that brings an enormous amount of features. I’ve
been working with Postgres a lot and in each project, I had to invent a wheel
from scratch: add JSON support, type mapping, smart ResultSet
processing, and
so on. I strongly believe there should be a client that pairs Clojure with
Postgres seamlessly when all the features are available out of the box.
Here is a brief list of the benefits of this project:
-
Written in pure Clojure and thus is completely transparent for users and developers;
-
Supports a lot of Clojure and Java types including
java.time.*
(see the dedicated section in the documentation); -
Extendable encoding and decoding: adding a new type means just extending a multimethod;
-
Implements both Simple and Extended Postgres Wire protocols;
-
Implements both text and binary content encoding and decoding;
-
Easy to debug what goes through the wire;
-
Reducing the result on the fly, custom reducers; various ways to process the data;
-
SAML authentication out from the box; JDBC still fails when handling it (“unknown auth code 10”);
-
Tested with Postgres 11, 12, 13, 14, 15, and 16-beta (integration tests with multiple Docker images);
-
And more.
Installation
General Notes
Although PG is a set of modules, they all have the same version when deployed to Clojars. For example:
Lein:
[com.github.igrishaev/pg-client "0.1.6"]
[com.github.igrishaev/pg-pool "0.1.6"]
Deps:
{com.github.igrishaev/pg-client {:mvn/version "0.1.6"}
Lein users may specify a global pg-version
variable on top of the
project.clj
and reference it as follows:
;; project.clj
(def pg-version "0.1.6")
(defproject ...
:dependencies
[...
[com.github.igrishaev/pg-client ~pg-version]
[com.github.igrishaev/pg-pool ~pg-version]])
Usually, you don’t need to specify more than one package because they depend on each other and will be download automatically.
Client
The pg-client
module ships a client access to Postgres. Since the connection
pool depends on logging facility, it’s shipped in a separate package.
[com.github.igrishaev/pg-client "0.1.6"]
Deps:
{com.github.igrishaev/pg-client {:mvn/version "0.1.6"}
Connection Pool
The client depends on pool so there is no need to specify it explicitly.
[com.github.igrishaev/pg-pool "0.1.6"]
Deps:
{com.github.igrishaev/pg-pool {:mvn/version "0.1.6"}
JSON extension
A package that extends the client with reading and writing JSON objects.
[com.github.igrishaev/pg-json "0.1.6"]
Deps:
{com.github.igrishaev/pg-json {:mvn/version "0.1.6"}
Joda Time extension
Extends the client with Joda Time support.
[com.github.igrishaev/pg-joda-time "0.1.6"]
Deps:
{com.github.igrishaev/pg-joda-time {:mvn/version "0.1.6"}
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter